[kernel] r7685 - in dists/trunk/linux-2.6/debian: . patches/bugfix
patches/bugfix/sparc patches/series
maximilian attems
maks-guest at alioth.debian.org
Thu Nov 2 17:50:39 UTC 2006
Author: maks-guest
Date: Thu Nov 2 18:50:36 2006
New Revision: 7685
Added:
dists/trunk/linux-2.6/debian/patches/bugfix/2.6.18.2
Removed:
dists/trunk/linux-2.6/debian/patches/bugfix/__div64_32-for-31-bit.patch
dists/trunk/linux-2.6/debian/patches/bugfix/audit-syscalls.patch
dists/trunk/linux-2.6/debian/patches/bugfix/net-sky2-lockup.patch
dists/trunk/linux-2.6/debian/patches/bugfix/sparc/sunblade-clock-hang.patch
dists/trunk/linux-2.6/debian/patches/bugfix/x86-64-c3_timer.patch
Modified:
dists/trunk/linux-2.6/debian/changelog
dists/trunk/linux-2.6/debian/patches/series/4
Log:
merge huge 2.6.18.2-rc1 (minus Makefile and bcm43xx snipp)
delete all the included but not yet released patches
revert the others
Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog (original)
+++ dists/trunk/linux-2.6/debian/changelog Thu Nov 2 18:50:36 2006
@@ -1,4 +1,4 @@
-linux-2.6 (2.6.18-4) UNRELEASED; urgency=low
+linux-2.6 (2.6.18-4) unstable; urgency=low
[ Norbert Tretkowski ]
* [alpha] Switched to gcc-4.1.
@@ -51,6 +51,9 @@
* [s390]: Fix funny timespeed on hercules emulator. (closes: 395247)
* bcm43xx: Add full netdev watchout timeout patch. (closes: 392065)
Thanks Sjoerd Simons <sjoerd at spring.luon.net> for the testing.
+ * Add stable prerelease 2.6.18.2:
+ - Remove not yet released, revert the included patches.
+ - Keep aboves bcm43xx fix, it's more complete.
[ Sven Luther ]
* [powerpc] Added exception alignement patch from Benjamin Herrenschmidt.
@@ -94,7 +97,7 @@
- bugfix/mips/dec-serial.patch, replaces mips-dec-serial.patch, fix
serial console handling on DECstations.
- -- Frederik Schüler <fs at debian.org> Wed, 1 Nov 2006 23:44:06 +0100
+ -- maximilian attems <maks at sternwelten.at> Thu, 2 Nov 2006 18:47:45 +0100
linux-2.6 (2.6.18-3) unstable; urgency=low
Added: dists/trunk/linux-2.6/debian/patches/bugfix/2.6.18.2
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/2.6.18.2 Thu Nov 2 18:50:36 2006
@@ -0,0 +1,2703 @@
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/i386/Kconfig.cpu linux-2.6.18.2-rc1/arch/i386/Kconfig.cpu
+--- linux-2.6.18.1/arch/i386/Kconfig.cpu 2006-10-31 21:13:26.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/i386/Kconfig.cpu 2006-10-31 16:13:26.000000000 -0800
+@@ -7,6 +7,7 @@
+
+ config M386
+ bool "386"
++ depends on !UML
+ ---help---
+ This is the processor type of your CPU. This information is used for
+ optimizing purposes. In order to compile a kernel that can run on
+@@ -301,7 +302,7 @@
+
+ config X86_USE_3DNOW
+ bool
+- depends on MCYRIXIII || MK7 || MGEODE_LX
++ depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
+ default y
+
+ config X86_OOSTORE
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/i386/kernel/alternative.c linux-2.6.18.2-rc1/arch/i386/kernel/alternative.c
+--- linux-2.6.18.1/arch/i386/kernel/alternative.c 2006-10-31 21:13:26.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/i386/kernel/alternative.c 2006-10-31 16:13:26.000000000 -0800
+@@ -344,6 +344,7 @@
+
+ void __init alternative_instructions(void)
+ {
++ unsigned long flags;
+ if (no_replacement) {
+ printk(KERN_INFO "(SMP-)alternatives turned off\n");
+ free_init_pages("SMP alternatives",
+@@ -351,6 +352,8 @@
+ (unsigned long)__smp_alt_end);
+ return;
+ }
++
++ local_irq_save(flags);
+ apply_alternatives(__alt_instructions, __alt_instructions_end);
+
+ /* switch to patch-once-at-boottime-only mode and free the
+@@ -386,4 +389,5 @@
+ alternatives_smp_switch(0);
+ }
+ #endif
++ local_irq_restore(flags);
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/powerpc/configs/pseries_defconfig linux-2.6.18.2-rc1/arch/powerpc/configs/pseries_defconfig
+--- linux-2.6.18.1/arch/powerpc/configs/pseries_defconfig 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/powerpc/configs/pseries_defconfig 2006-10-31 16:13:27.000000000 -0800
+@@ -184,6 +184,7 @@
+ CONFIG_MIGRATION=y
+ CONFIG_RESOURCES_64BIT=y
+ CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
++CONFIG_NODES_SPAN_OTHER_NODES=y
+ # CONFIG_PPC_64K_PAGES is not set
+ CONFIG_SCHED_SMT=y
+ CONFIG_PROC_DEVICETREE=y
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/powerpc/Kconfig linux-2.6.18.2-rc1/arch/powerpc/Kconfig
+--- linux-2.6.18.1/arch/powerpc/Kconfig 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/powerpc/Kconfig 2006-10-31 16:13:27.000000000 -0800
+@@ -729,6 +729,15 @@
+ def_bool y
+ depends on MEMORY_HOTPLUG
+
++# Some NUMA nodes have memory ranges that span
++# other nodes. Even though a pfn is valid and
++# between a node's start and end pfns, it may not
++# reside on that node. See memmap_init_zone()
++# for details.
++config NODES_SPAN_OTHER_NODES
++ def_bool y
++ depends on NEED_MULTIPLE_NODES
++
+ config PPC_64K_PAGES
+ bool "64k page size"
+ depends on PPC64
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/s390/Kconfig linux-2.6.18.2-rc1/arch/s390/Kconfig
+--- linux-2.6.18.1/arch/s390/Kconfig 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/s390/Kconfig 2006-10-31 16:13:26.000000000 -0800
+@@ -51,6 +51,10 @@
+ Select this option if you have a 64 bit IBM zSeries machine
+ and want to use the 64 bit addressing mode.
+
++config 32BIT
++ bool
++ default y if !64BIT
++
+ config SMP
+ bool "Symmetric multi-processing support"
+ ---help---
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/s390/lib/div64.c linux-2.6.18.2-rc1/arch/s390/lib/div64.c
+--- linux-2.6.18.1/arch/s390/lib/div64.c 1969-12-31 16:00:00.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/s390/lib/div64.c 2006-10-31 16:13:26.000000000 -0800
+@@ -0,0 +1,151 @@
++/*
++ * arch/s390/lib/div64.c
++ *
++ * __div64_32 implementation for 31 bit.
++ *
++ * Copyright (C) IBM Corp. 2006
++ * Author(s): Martin Schwidefsky (schwidefsky at de.ibm.com),
++ */
++
++#include <linux/types.h>
++#include <linux/module.h>
++
++#ifdef CONFIG_MARCH_G5
++
++/*
++ * Function to divide an unsigned 64 bit integer by an unsigned
++ * 31 bit integer using signed 64/32 bit division.
++ */
++static uint32_t __div64_31(uint64_t *n, uint32_t base)
++{
++ register uint32_t reg2 asm("2");
++ register uint32_t reg3 asm("3");
++ uint32_t *words = (uint32_t *) n;
++ uint32_t tmp;
++
++ /* Special case base==1, remainder = 0, quotient = n */
++ if (base == 1)
++ return 0;
++ /*
++ * Special case base==0 will cause a fixed point divide exception
++ * on the dr instruction and may not happen anyway. For the
++ * following calculation we can assume base > 1. The first
++ * signed 64 / 32 bit division with an upper half of 0 will
++ * give the correct upper half of the 64 bit quotient.
++ */
++ reg2 = 0UL;
++ reg3 = words[0];
++ asm volatile(
++ " dr %0,%2\n"
++ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
++ words[0] = reg3;
++ reg3 = words[1];
++ /*
++ * To get the lower half of the 64 bit quotient and the 32 bit
++ * remainder we have to use a little trick. Since we only have
++ * a signed division the quotient can get too big. To avoid this
++ * the 64 bit dividend is halved, then the signed division will
++ * work. Afterwards the quotient and the remainder are doubled.
++ * If the last bit of the dividend has been one the remainder
++ * is increased by one then checked against the base. If the
++ * remainder has overflown subtract base and increase the
++ * quotient. Simple, no ?
++ */
++ asm volatile(
++ " nr %2,%1\n"
++ " srdl %0,1\n"
++ " dr %0,%3\n"
++ " alr %0,%0\n"
++ " alr %1,%1\n"
++ " alr %0,%2\n"
++ " clr %0,%3\n"
++ " jl 0f\n"
++ " slr %0,%3\n"
++ " alr %1,%2\n"
++ "0:\n"
++ : "+d" (reg2), "+d" (reg3), "=d" (tmp)
++ : "d" (base), "2" (1UL) : "cc" );
++ words[1] = reg3;
++ return reg2;
++}
++
++/*
++ * Function to divide an unsigned 64 bit integer by an unsigned
++ * 32 bit integer using the unsigned 64/31 bit division.
++ */
++uint32_t __div64_32(uint64_t *n, uint32_t base)
++{
++ uint32_t r;
++
++ /*
++ * If the most significant bit of base is set, divide n by
++ * (base/2). That allows to use 64/31 bit division and gives a
++ * good approximation of the result: n = (base/2)*q + r. The
++ * result needs to be corrected with two simple transformations.
++ * If base is already < 2^31-1 __div64_31 can be used directly.
++ */
++ r = __div64_31(n, ((signed) base < 0) ? (base/2) : base);
++ if ((signed) base < 0) {
++ uint64_t q = *n;
++ /*
++ * First transformation:
++ * n = (base/2)*q + r
++ * = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r
++ * Since r < (base/2), r + (base/2) < base.
++ * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0)
++ * n = ((base/2)*2)*q1 + r1 with r1 < base.
++ */
++ if (q & 1)
++ r += base/2;
++ q >>= 1;
++ /*
++ * Second transformation. ((base/2)*2) could have lost the
++ * last bit.
++ * n = ((base/2)*2)*q1 + r1
++ * = base*q1 - ((base&1) ? q1 : 0) + r1
++ */
++ if (base & 1) {
++ int64_t rx = r - q;
++ /*
++ * base is >= 2^31. The worst case for the while
++ * loop is n=2^64-1 base=2^31+1. That gives a
++ * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since
++ * base >= 2^31 the loop is finished after a maximum
++ * of three iterations.
++ */
++ while (rx < 0) {
++ rx += base;
++ q--;
++ }
++ r = rx;
++ }
++ *n = q;
++ }
++ return r;
++}
++
++#else /* MARCH_G5 */
++
++uint32_t __div64_32(uint64_t *n, uint32_t base)
++{
++ register uint32_t reg2 asm("2");
++ register uint32_t reg3 asm("3");
++ uint32_t *words = (uint32_t *) n;
++
++ reg2 = 0UL;
++ reg3 = words[0];
++ asm volatile(
++ " dlr %0,%2\n"
++ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
++ words[0] = reg3;
++ reg3 = words[1];
++ asm volatile(
++ " dlr %0,%2\n"
++ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
++ words[1] = reg3;
++ return reg2;
++}
++
++#endif /* MARCH_G5 */
++
++EXPORT_SYMBOL(__div64_32);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/s390/lib/Makefile linux-2.6.18.2-rc1/arch/s390/lib/Makefile
+--- linux-2.6.18.1/arch/s390/lib/Makefile 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/s390/lib/Makefile 2006-10-31 16:13:26.000000000 -0800
+@@ -7,3 +7,4 @@
+ lib-y += delay.o string.o
+ lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
+ lib-$(CONFIG_SMP) += spinlock.o
++lib-$(CONFIG_32BIT) += div64.o
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/sparc64/kernel/central.c linux-2.6.18.2-rc1/arch/sparc64/kernel/central.c
+--- linux-2.6.18.1/arch/sparc64/kernel/central.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/sparc64/kernel/central.c 2006-10-31 16:13:26.000000000 -0800
+@@ -126,6 +126,10 @@
+ int board;
+ u32 tmp;
+
++ if (dp->parent &&
++ dp->parent->parent != NULL)
++ continue;
++
+ fhc = (struct linux_fhc *)
+ central_alloc_bootmem(sizeof(struct linux_fhc));
+ if (fhc == NULL)
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/sparc64/kernel/of_device.c linux-2.6.18.2-rc1/arch/sparc64/kernel/of_device.c
+--- linux-2.6.18.1/arch/sparc64/kernel/of_device.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/sparc64/kernel/of_device.c 2006-10-31 16:13:26.000000000 -0800
+@@ -398,16 +398,22 @@
+ *sizec = 1;
+ }
+
+-static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna)
+-{
+- return of_bus_default_map(addr, range, na, ns, pna);
+-}
+-
+-static unsigned int of_bus_sbus_get_flags(u32 *addr)
++/*
++ * FHC/Central bus specific translator.
++ *
++ * This is just needed to hard-code the address and size cell
++ * counts. 'fhc' and 'central' nodes lack the #address-cells and
++ * #size-cells properties, and if you walk to the root on such
++ * Enterprise boxes all you'll get is a #size-cells of 2 which is
++ * not what we want to use.
++ */
++static int of_bus_fhc_match(struct device_node *np)
+ {
+- return IORESOURCE_MEM;
++ return !strcmp(np->name, "fhc") ||
++ !strcmp(np->name, "central");
+ }
+
++#define of_bus_fhc_count_cells of_bus_sbus_count_cells
+
+ /*
+ * Array of bus specific translators
+@@ -429,8 +435,17 @@
+ .addr_prop_name = "reg",
+ .match = of_bus_sbus_match,
+ .count_cells = of_bus_sbus_count_cells,
+- .map = of_bus_sbus_map,
+- .get_flags = of_bus_sbus_get_flags,
++ .map = of_bus_default_map,
++ .get_flags = of_bus_default_get_flags,
++ },
++ /* FHC */
++ {
++ .name = "fhc",
++ .addr_prop_name = "reg",
++ .match = of_bus_fhc_match,
++ .count_cells = of_bus_fhc_count_cells,
++ .map = of_bus_default_map,
++ .get_flags = of_bus_default_get_flags,
+ },
+ /* Default */
+ {
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/sparc64/kernel/pci_common.c linux-2.6.18.2-rc1/arch/sparc64/kernel/pci_common.c
+--- linux-2.6.18.1/arch/sparc64/kernel/pci_common.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/sparc64/kernel/pci_common.c 2006-10-31 16:13:27.000000000 -0800
+@@ -330,19 +330,6 @@
+ return res;
+ }
+
+-static int __init pdev_resource_collisions_expected(struct pci_dev *pdev)
+-{
+- if (pdev->vendor != PCI_VENDOR_ID_SUN)
+- return 0;
+-
+- if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS ||
+- pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 ||
+- pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
+- return 1;
+-
+- return 0;
+-}
+-
+ static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
+ struct pci_dev *pdev)
+ {
+@@ -400,19 +387,23 @@
+ pbm->parent->resource_adjust(pdev, res, root);
+
+ if (request_resource(root, res) < 0) {
++ int rnum;
++
+ /* OK, there is some conflict. But this is fine
+ * since we'll reassign it in the fixup pass.
+ *
+- * We notify the user that OBP made an error if it
+- * is a case we don't expect.
++ * Do not print the warning for ROM resources
++ * as such a conflict is quite common and
++ * harmless as the ROM bar is disabled.
+ */
+- if (!pdev_resource_collisions_expected(pdev)) {
+- printk(KERN_ERR "PCI: Address space collision on region %ld "
++ rnum = (res - &pdev->resource[0]);
++ if (rnum != PCI_ROM_RESOURCE)
++ printk(KERN_ERR "PCI: Resource collision, "
++ "region %d "
+ "[%016lx:%016lx] of device %s\n",
+- (res - &pdev->resource[0]),
++ rnum,
+ res->start, res->end,
+ pci_name(pdev));
+- }
+ }
+ }
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/sparc64/kernel/pci_iommu.c linux-2.6.18.2-rc1/arch/sparc64/kernel/pci_iommu.c
+--- linux-2.6.18.1/arch/sparc64/kernel/pci_iommu.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/sparc64/kernel/pci_iommu.c 2006-10-31 16:13:26.000000000 -0800
+@@ -281,7 +281,7 @@
+
+ spin_lock_irqsave(&iommu->lock, flags);
+
+- free_npages(iommu, dvma, npages);
++ free_npages(iommu, dvma - iommu->page_table_map_base, npages);
+
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/sparc64/kernel/pci_sabre.c linux-2.6.18.2-rc1/arch/sparc64/kernel/pci_sabre.c
+--- linux-2.6.18.1/arch/sparc64/kernel/pci_sabre.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/sparc64/kernel/pci_sabre.c 2006-10-31 16:13:27.000000000 -0800
+@@ -1196,7 +1196,7 @@
+ &pbm->mem_space);
+ }
+
+-static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin)
++static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end)
+ {
+ struct pci_pbm_info *pbm;
+ struct device_node *node;
+@@ -1261,6 +1261,8 @@
+ node = node->sibling;
+ }
+ if (simbas_found == 0) {
++ struct resource *rp;
++
+ /* No APBs underneath, probably this is a hummingbird
+ * system.
+ */
+@@ -1302,8 +1304,10 @@
+ pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL;
+ pbm->io_space.flags = IORESOURCE_IO;
+
+- pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE;
+- pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL;
++ pbm->mem_space.start =
++ (p->pbm_A.controller_regs + SABRE_MEMSPACE);
++ pbm->mem_space.end =
++ (pbm->mem_space.start + ((1UL << 32UL) - 1UL));
+ pbm->mem_space.flags = IORESOURCE_MEM;
+
+ if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
+@@ -1315,6 +1319,17 @@
+ prom_halt();
+ }
+
++ rp = kmalloc(sizeof(*rp), GFP_KERNEL);
++ if (!rp) {
++ prom_printf("Cannot allocate IOMMU resource.\n");
++ prom_halt();
++ }
++ rp->name = "IOMMU";
++ rp->start = pbm->mem_space.start + (unsigned long) dma_start;
++ rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
++ rp->flags = IORESOURCE_BUSY;
++ request_resource(&pbm->mem_space, rp);
++
+ pci_register_legacy_regions(&pbm->io_space,
+ &pbm->mem_space);
+ }
+@@ -1450,5 +1465,5 @@
+ /*
+ * Look for APB underneath.
+ */
+- sabre_pbm_init(p, dp, vdma[0]);
++ sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]);
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/sparc64/kernel/prom.c linux-2.6.18.2-rc1/arch/sparc64/kernel/prom.c
+--- linux-2.6.18.1/arch/sparc64/kernel/prom.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/sparc64/kernel/prom.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1080,23 +1080,22 @@
+
+ static void irq_trans_init(struct device_node *dp)
+ {
+- const char *model;
+ #ifdef CONFIG_PCI
++ const char *model;
+ int i;
+ #endif
+
++#ifdef CONFIG_PCI
+ model = of_get_property(dp, "model", NULL);
+ if (!model)
+ model = of_get_property(dp, "compatible", NULL);
+- if (!model)
+- return;
+-
+-#ifdef CONFIG_PCI
+- for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
+- struct irq_trans *t = &pci_irq_trans_table[i];
++ if (model) {
++ for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
++ struct irq_trans *t = &pci_irq_trans_table[i];
+
+- if (!strcmp(model, t->name))
+- return t->init(dp);
++ if (!strcmp(model, t->name))
++ return t->init(dp);
++ }
+ }
+ #endif
+ #ifdef CONFIG_SBUS
+@@ -1104,8 +1103,9 @@
+ !strcmp(dp->name, "sbi"))
+ return sbus_irq_trans_init(dp);
+ #endif
+- if (!strcmp(dp->name, "central"))
+- return central_irq_trans_init(dp->child);
++ if (!strcmp(dp->name, "fhc") &&
++ !strcmp(dp->parent->name, "central"))
++ return central_irq_trans_init(dp);
+ if (!strcmp(dp->name, "virtual-devices"))
+ return sun4v_vdev_irq_trans_init(dp);
+ }
+@@ -1517,7 +1517,7 @@
+ return buf;
+ }
+
+-static struct device_node * __init create_node(phandle node)
++static struct device_node * __init create_node(phandle node, struct device_node *parent)
+ {
+ struct device_node *dp;
+
+@@ -1526,6 +1526,7 @@
+
+ dp = prom_early_alloc(sizeof(*dp));
+ dp->unique_id = unique_id++;
++ dp->parent = parent;
+
+ kref_init(&dp->kref);
+
+@@ -1544,12 +1545,11 @@
+ {
+ struct device_node *dp;
+
+- dp = create_node(node);
++ dp = create_node(node, parent);
+ if (dp) {
+ *(*nextp) = dp;
+ *nextp = &dp->allnext;
+
+- dp->parent = parent;
+ dp->path_component_name = build_path_component(dp);
+ dp->full_name = build_full_name(dp);
+
+@@ -1565,7 +1565,7 @@
+ {
+ struct device_node **nextp;
+
+- allnodes = create_node(prom_root_node);
++ allnodes = create_node(prom_root_node, NULL);
+ allnodes->path_component_name = "";
+ allnodes->full_name = "/";
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/um/include/kern_util.h linux-2.6.18.2-rc1/arch/um/include/kern_util.h
+--- linux-2.6.18.1/arch/um/include/kern_util.h 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/um/include/kern_util.h 2006-10-31 16:13:26.000000000 -0800
+@@ -6,7 +6,6 @@
+ #ifndef __KERN_UTIL_H__
+ #define __KERN_UTIL_H__
+
+-#include "linux/threads.h"
+ #include "sysdep/ptrace.h"
+ #include "sysdep/faultinfo.h"
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/um/os-Linux/sys-i386/tls.c linux-2.6.18.2-rc1/arch/um/os-Linux/sys-i386/tls.c
+--- linux-2.6.18.1/arch/um/os-Linux/sys-i386/tls.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/um/os-Linux/sys-i386/tls.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1,4 +1,6 @@
+ #include <errno.h>
++#include <sys/syscall.h>
++#include <unistd.h>
+ #include <linux/unistd.h>
+ #include "sysdep/tls.h"
+ #include "user_util.h"
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/um/os-Linux/tls.c linux-2.6.18.2-rc1/arch/um/os-Linux/tls.c
+--- linux-2.6.18.1/arch/um/os-Linux/tls.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/um/os-Linux/tls.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1,6 +1,8 @@
+ #include <errno.h>
+ #include <sys/ptrace.h>
++#include <sys/syscall.h>
+ #include <asm/ldt.h>
++#include <unistd.h>
+ #include "sysdep/tls.h"
+ #include "uml-config.h"
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/um/sys-x86_64/stub_segv.c linux-2.6.18.2-rc1/arch/um/sys-x86_64/stub_segv.c
+--- linux-2.6.18.1/arch/um/sys-x86_64/stub_segv.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/um/sys-x86_64/stub_segv.c 2006-10-31 16:13:26.000000000 -0800
+@@ -5,7 +5,6 @@
+
+ #include <stddef.h>
+ #include <signal.h>
+-#include <linux/compiler.h>
+ #include <asm/unistd.h>
+ #include "uml-config.h"
+ #include "sysdep/sigcontext.h"
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/arch/x86_64/kernel/time.c linux-2.6.18.2-rc1/arch/x86_64/kernel/time.c
+--- linux-2.6.18.1/arch/x86_64/kernel/time.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/arch/x86_64/kernel/time.c 2006-10-31 16:13:26.000000000 -0800
+@@ -960,7 +960,7 @@
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+ #ifdef CONFIG_ACPI
+ /* But TSC doesn't tick in C3 so don't use it there */
+- if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
++ if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000)
+ return 1;
+ #endif
+ return 0;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/block/ll_rw_blk.c linux-2.6.18.2-rc1/block/ll_rw_blk.c
+--- linux-2.6.18.1/block/ll_rw_blk.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/block/ll_rw_blk.c 2006-10-31 16:13:27.000000000 -0800
+@@ -3021,6 +3021,7 @@
+ {
+ request_queue_t *q;
+ sector_t maxsector;
++ sector_t old_sector;
+ int ret, nr_sectors = bio_sectors(bio);
+ dev_t old_dev;
+
+@@ -3049,7 +3050,7 @@
+ * NOTE: we don't repeat the blk_size check for each new device.
+ * Stacking drivers are expected to know what they are doing.
+ */
+- maxsector = -1;
++ old_sector = -1;
+ old_dev = 0;
+ do {
+ char b[BDEVNAME_SIZE];
+@@ -3083,15 +3084,30 @@
+ */
+ blk_partition_remap(bio);
+
+- if (maxsector != -1)
++ if (old_sector != -1)
+ blk_add_trace_remap(q, bio, old_dev, bio->bi_sector,
+- maxsector);
++ old_sector);
+
+ blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
+
+- maxsector = bio->bi_sector;
++ old_sector = bio->bi_sector;
+ old_dev = bio->bi_bdev->bd_dev;
+
++ maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
++ if (maxsector) {
++ sector_t sector = bio->bi_sector;
++
++ if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
++ /*
++ * This may well happen - partitions are not checked
++ * to make sure they are within the size of the
++ * whole device.
++ */
++ handle_bad_sector(bio);
++ goto end_io;
++ }
++ }
++
+ ret = q->make_request_fn(q, bio);
+ } while (ret);
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/block/DAC960.c linux-2.6.18.2-rc1/drivers/block/DAC960.c
+--- linux-2.6.18.1/drivers/block/DAC960.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/block/DAC960.c 2006-10-31 16:13:26.000000000 -0800
+@@ -7115,7 +7115,7 @@
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
+- .subvendor = PCI_ANY_ID,
++ .subvendor = PCI_VENDOR_ID_MYLEX,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_GEM_privdata,
+ },
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/char/hw_random/intel-rng.c linux-2.6.18.2-rc1/drivers/char/hw_random/intel-rng.c
+--- linux-2.6.18.1/drivers/char/hw_random/intel-rng.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/char/hw_random/intel-rng.c 2006-10-31 16:13:26.000000000 -0800
+@@ -50,6 +50,43 @@
+ #define INTEL_RNG_ADDR_LEN 3
+
+ /*
++ * LPC bridge PCI config space registers
++ */
++#define FWH_DEC_EN1_REG_OLD 0xe3
++#define FWH_DEC_EN1_REG_NEW 0xd9 /* high byte of 16-bit register */
++#define FWH_F8_EN_MASK 0x80
++
++#define BIOS_CNTL_REG_OLD 0x4e
++#define BIOS_CNTL_REG_NEW 0xdc
++#define BIOS_CNTL_WRITE_ENABLE_MASK 0x01
++#define BIOS_CNTL_LOCK_ENABLE_MASK 0x02
++
++/*
++ * Magic address at which Intel Firmware Hubs get accessed
++ */
++#define INTEL_FWH_ADDR 0xffff0000
++#define INTEL_FWH_ADDR_LEN 2
++
++/*
++ * Intel Firmware Hub command codes (write to any address inside the device)
++ */
++#define INTEL_FWH_RESET_CMD 0xff /* aka READ_ARRAY */
++#define INTEL_FWH_READ_ID_CMD 0x90
++
++/*
++ * Intel Firmware Hub Read ID command result addresses
++ */
++#define INTEL_FWH_MANUFACTURER_CODE_ADDRESS 0x000000
++#define INTEL_FWH_DEVICE_CODE_ADDRESS 0x000001
++
++/*
++ * Intel Firmware Hub Read ID command result values
++ */
++#define INTEL_FWH_MANUFACTURER_CODE 0x89
++#define INTEL_FWH_DEVICE_CODE_8M 0xac
++#define INTEL_FWH_DEVICE_CODE_4M 0xad
++
++/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+@@ -58,12 +95,50 @@
+ * want to register another driver on the same PCI id.
+ */
+ static const struct pci_device_id pci_tbl[] = {
+- { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+- { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+- { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+- { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+- { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+- { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
++/* AA
++ { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
++ { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
++/* AB
++ { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
++ { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
++/* ??
++ { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
++/* BAM, CAM, DBM, FBM, GxM
++ { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
++ { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
++ { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
++ { 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
++ { 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
++ { 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
++ { 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
++/* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
++ { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
++ { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
++ { 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
++ { 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
++ { 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
++ { 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
++ { 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
++ { 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
++ { 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
++/* E
++ { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
++ { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E */
+ { 0, }, /* terminate list */
+ };
+ MODULE_DEVICE_TABLE(pci, pci_tbl);
+@@ -138,22 +213,115 @@
+ };
+
+
++#ifdef CONFIG_SMP
++static char __initdata waitflag;
++
++static void __init intel_init_wait(void *unused)
++{
++ while (waitflag)
++ cpu_relax();
++}
++#endif
++
+ static int __init mod_init(void)
+ {
+ int err = -ENODEV;
++ unsigned i;
++ struct pci_dev *dev = NULL;
+ void __iomem *mem;
+- u8 hw_status;
++ unsigned long flags;
++ u8 bios_cntl_off, fwh_dec_en1_off;
++ u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
++ u8 hw_status, mfc, dvc;
++
++ for (i = 0; !dev && pci_tbl[i].vendor; ++i)
++ dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL);
+
+- if (!pci_dev_present(pci_tbl))
++ if (!dev)
+ goto out; /* Device not found. */
+
++ /* Check for Intel 82802 */
++ if (dev->device < 0x2640) {
++ fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
++ bios_cntl_off = BIOS_CNTL_REG_OLD;
++ } else {
++ fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
++ bios_cntl_off = BIOS_CNTL_REG_NEW;
++ }
++
++ pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
++ pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
++
++ mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
++ if (mem == NULL) {
++ pci_dev_put(dev);
++ err = -EBUSY;
++ goto out;
++ }
++
++ /*
++ * Since the BIOS code/data is going to disappear from its normal
++ * location with the Read ID command, all activity on the system
++ * must be stopped until the state is back to normal.
++ */
++#ifdef CONFIG_SMP
++ set_mb(waitflag, 1);
++ if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
++ set_mb(waitflag, 0);
++ pci_dev_put(dev);
++ printk(KERN_ERR PFX "cannot run on all processors\n");
++ err = -EAGAIN;
++ goto err_unmap;
++ }
++#endif
++ local_irq_save(flags);
++
++ if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
++ pci_write_config_byte(dev,
++ fwh_dec_en1_off,
++ fwh_dec_en1_val | FWH_F8_EN_MASK);
++ if (!(bios_cntl_val &
++ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
++ pci_write_config_byte(dev,
++ bios_cntl_off,
++ bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
++
++ writeb(INTEL_FWH_RESET_CMD, mem);
++ writeb(INTEL_FWH_READ_ID_CMD, mem);
++ mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
++ dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
++ writeb(INTEL_FWH_RESET_CMD, mem);
++
++ if (!(bios_cntl_val &
++ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
++ pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
++ if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
++ pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
++
++ local_irq_restore(flags);
++#ifdef CONFIG_SMP
++ /* Tell other CPUs to resume. */
++ set_mb(waitflag, 0);
++#endif
++
++ iounmap(mem);
++ pci_dev_put(dev);
++
++ if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
++ (dvc != INTEL_FWH_DEVICE_CODE_8M &&
++ dvc != INTEL_FWH_DEVICE_CODE_4M)) {
++ printk(KERN_ERR PFX "FWH not detected\n");
++ err = -ENODEV;
++ goto out;
++ }
++
+ err = -ENOMEM;
+ mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
+ if (!mem)
+ goto out;
+ intel_rng.priv = (unsigned long)mem;
+
+- /* Check for Intel 82802 */
++ /* Check for Random Number Generator */
+ err = -ENODEV;
+ hw_status = hwstatus_get(mem);
+ if ((hw_status & INTEL_RNG_PRESENT) == 0)
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/char/watchdog/sc1200wdt.c linux-2.6.18.2-rc1/drivers/char/watchdog/sc1200wdt.c
+--- linux-2.6.18.1/drivers/char/watchdog/sc1200wdt.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/char/watchdog/sc1200wdt.c 2006-10-31 16:13:26.000000000 -0800
+@@ -392,7 +392,7 @@
+ if (io == -1) {
+ printk(KERN_ERR PFX "io parameter must be specified\n");
+ ret = -EINVAL;
+- goto out_clean;
++ goto out_pnp;
+ }
+
+ #if defined CONFIG_PNP
+@@ -405,7 +405,7 @@
+ if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
+ printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
+ ret = -EBUSY;
+- goto out_clean;
++ goto out_pnp;
+ }
+
+ ret = sc1200wdt_probe();
+@@ -435,6 +435,11 @@
+ out_io:
+ release_region(io, io_len);
+
++out_pnp:
++#if defined CONFIG_PNP
++ if (isapnp)
++ pnp_unregister_driver(&scl200wdt_pnp_driver);
++#endif
+ goto out_clean;
+ }
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/ide/pci/generic.c linux-2.6.18.2-rc1/drivers/ide/pci/generic.c
+--- linux-2.6.18.1/drivers/ide/pci/generic.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/ide/pci/generic.c 2006-10-31 16:13:27.000000000 -0800
+@@ -242,8 +242,10 @@
+ (!(PCI_FUNC(dev->devfn) & 1)))
+ goto out;
+
+- if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
+- goto out;
++ if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
++ if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
++ goto out;
++ }
+
+ if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/infiniband/hw/mthca/mthca_cq.c linux-2.6.18.2-rc1/drivers/infiniband/hw/mthca/mthca_cq.c
+--- linux-2.6.18.1/drivers/infiniband/hw/mthca/mthca_cq.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/infiniband/hw/mthca/mthca_cq.c 2006-10-31 16:13:26.000000000 -0800
+@@ -39,6 +39,8 @@
+ #include <linux/init.h>
+ #include <linux/hardirq.h>
+
++#include <asm/io.h>
++
+ #include <rdma/ib_pack.h>
+
+ #include "mthca_dev.h"
+@@ -210,6 +212,11 @@
+ mthca_write64(doorbell,
+ dev->kar + MTHCA_CQ_DOORBELL,
+ MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
++ /*
++ * Make sure doorbells don't leak out of CQ spinlock
++ * and reach the HCA out of order:
++ */
++ mmiowb();
+ }
+ }
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/infiniband/hw/mthca/mthca_qp.c linux-2.6.18.2-rc1/drivers/infiniband/hw/mthca/mthca_qp.c
+--- linux-2.6.18.1/drivers/infiniband/hw/mthca/mthca_qp.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/infiniband/hw/mthca/mthca_qp.c 2006-10-31 16:13:26.000000000 -0800
+@@ -39,6 +39,8 @@
+ #include <linux/string.h>
+ #include <linux/slab.h>
+
++#include <asm/io.h>
++
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_cache.h>
+ #include <rdma/ib_pack.h>
+@@ -1730,6 +1732,11 @@
+ mthca_write64(doorbell,
+ dev->kar + MTHCA_SEND_DOORBELL,
+ MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
++ /*
++ * Make sure doorbells don't leak out of SQ spinlock
++ * and reach the HCA out of order:
++ */
++ mmiowb();
+ }
+
+ qp->sq.next_ind = ind;
+@@ -1849,6 +1856,12 @@
+ qp->rq.next_ind = ind;
+ qp->rq.head += nreq;
+
++ /*
++ * Make sure doorbells don't leak out of RQ spinlock and reach
++ * the HCA out of order:
++ */
++ mmiowb();
++
+ spin_unlock_irqrestore(&qp->rq.lock, flags);
+ return err;
+ }
+@@ -2110,6 +2123,12 @@
+ MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+ }
+
++ /*
++ * Make sure doorbells don't leak out of SQ spinlock and reach
++ * the HCA out of order:
++ */
++ mmiowb();
++
+ spin_unlock_irqrestore(&qp->sq.lock, flags);
+ return err;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/infiniband/hw/mthca/mthca_srq.c linux-2.6.18.2-rc1/drivers/infiniband/hw/mthca/mthca_srq.c
+--- linux-2.6.18.1/drivers/infiniband/hw/mthca/mthca_srq.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/infiniband/hw/mthca/mthca_srq.c 2006-10-31 16:13:26.000000000 -0800
+@@ -35,6 +35,8 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+
++#include <asm/io.h>
++
+ #include "mthca_dev.h"
+ #include "mthca_cmd.h"
+ #include "mthca_memfree.h"
+@@ -593,6 +595,12 @@
+ MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+ }
+
++ /*
++ * Make sure doorbells don't leak out of SRQ spinlock and
++ * reach the HCA out of order:
++ */
++ mmiowb();
++
+ spin_unlock_irqrestore(&srq->lock, flags);
+ return err;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-2.6.18.2-rc1/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+--- linux-2.6.18.1/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2006-10-31 16:13:26.000000000 -0800
+@@ -619,8 +619,10 @@
+ * The device could have been brought down between the start and when
+ * we get here, don't bring it back up if it's not configured up
+ */
+- if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
++ if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) {
+ ipoib_ib_dev_up(dev);
++ ipoib_mcast_restart_task(dev);
++ }
+
+ mutex_lock(&priv->vlan_mutex);
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/isdn/i4l/isdn_common.c linux-2.6.18.2-rc1/drivers/isdn/i4l/isdn_common.c
+--- linux-2.6.18.1/drivers/isdn/i4l/isdn_common.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/isdn/i4l/isdn_common.c 2006-10-31 16:13:27.000000000 -0800
+@@ -1134,9 +1134,12 @@
+ if (dev->drv[drvidx]->interface->readstat) {
+ if (count > dev->drv[drvidx]->stavail)
+ count = dev->drv[drvidx]->stavail;
+- len = dev->drv[drvidx]->interface->
+- readstat(buf, count, drvidx,
+- isdn_minor2chan(minor));
++ len = dev->drv[drvidx]->interface->readstat(buf, count,
++ drvidx, isdn_minor2chan(minor));
++ if (len < 0) {
++ retval = len;
++ goto out;
++ }
+ } else {
+ len = 0;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/macintosh/via-pmu-backlight.c linux-2.6.18.2-rc1/drivers/macintosh/via-pmu-backlight.c
+--- linux-2.6.18.1/drivers/macintosh/via-pmu-backlight.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/macintosh/via-pmu-backlight.c 2006-10-31 16:13:26.000000000 -0800
+@@ -16,7 +16,7 @@
+ #define MAX_PMU_LEVEL 0xFF
+
+ static struct backlight_properties pmu_backlight_data;
+-static spinlock_t pmu_backlight_lock;
++static DEFINE_SPINLOCK(pmu_backlight_lock);
+ static int sleeping;
+ static u8 bl_curve[FB_BACKLIGHT_LEVELS];
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/md/md.c linux-2.6.18.2-rc1/drivers/md/md.c
+--- linux-2.6.18.1/drivers/md/md.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/md/md.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1994,6 +1994,7 @@
+ kobject_init(&rdev->kobj);
+
+ rdev->desc_nr = -1;
++ rdev->saved_raid_disk = -1;
+ rdev->flags = 0;
+ rdev->data_offset = 0;
+ rdev->sb_events = 0;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/md/multipath.c linux-2.6.18.2-rc1/drivers/md/multipath.c
+--- linux-2.6.18.1/drivers/md/multipath.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/md/multipath.c 2006-10-31 16:13:26.000000000 -0800
+@@ -480,7 +480,7 @@
+ mdname(mddev));
+ goto out_free_conf;
+ }
+- mddev->degraded = conf->raid_disks = conf->working_disks;
++ mddev->degraded = conf->raid_disks - conf->working_disks;
+
+ conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
+ sizeof(struct multipath_bh));
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/md/raid10.c linux-2.6.18.2-rc1/drivers/md/raid10.c
+--- linux-2.6.18.1/drivers/md/raid10.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/md/raid10.c 2006-10-31 16:13:26.000000000 -0800
+@@ -2042,7 +2042,7 @@
+ disk = conf->mirrors + i;
+
+ if (!disk->rdev ||
+- !test_bit(In_sync, &rdev->flags)) {
++ !test_bit(In_sync, &disk->rdev->flags)) {
+ disk->head_position = 0;
+ mddev->degraded++;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c linux-2.6.18.2-rc1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+--- linux-2.6.18.1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/media/dvb/b2c2/flexcop-fe-tuner.c 2006-10-31 16:13:26.000000000 -0800
+@@ -527,7 +527,7 @@
+ /* try the air atsc 2nd generation (nxt2002) */
+ if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
+ fc->dev_type = FC_AIR_ATSC2;
+- dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv);
++ dvb_pll_attach(fc->fe, 0x61, NULL, &dvb_pll_samsung_tbmv);
+ info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
+ } else
+ /* try the air atsc 3nd generation (lgdt3303) */
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/media/dvb/frontends/dvb-pll.c linux-2.6.18.2-rc1/drivers/media/dvb/frontends/dvb-pll.c
+--- linux-2.6.18.1/drivers/media/dvb/frontends/dvb-pll.c 2006-10-31 21:13:27.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/media/dvb/frontends/dvb-pll.c 2006-10-31 16:13:26.000000000 -0800
+@@ -493,6 +493,9 @@
+ int i;
+ int result;
+
++ if (priv->i2c == NULL)
++ return -EINVAL;
++
+ for (i = 0; i < priv->pll_desc->count; i++) {
+ if (priv->pll_desc->entries[i].limit == 0)
+ break;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/media/video/cx88/cx88-dvb.c linux-2.6.18.2-rc1/drivers/media/video/cx88/cx88-dvb.c
+--- linux-2.6.18.1/drivers/media/video/cx88/cx88-dvb.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/media/video/cx88/cx88-dvb.c 2006-10-31 16:13:26.000000000 -0800
+@@ -576,7 +576,7 @@
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_pll_attach(dev->dvb.frontend, 0x60,
+- &dev->core->i2c_adap,
++ NULL,
+ &dvb_pll_thomson_dtt7579);
+ break;
+ }
+@@ -587,7 +587,7 @@
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_pll_attach(dev->dvb.frontend, 0x60,
+- &dev->core->i2c_adap,
++ NULL,
+ &dvb_pll_thomson_dtt7579);
+ }
+ #endif
+@@ -600,7 +600,7 @@
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_pll_attach(dev->dvb.frontend, 0x61,
+- &dev->core->i2c_adap,
++ NULL,
+ &dvb_pll_thomson_dtt7579);
+ break;
+ }
+@@ -611,7 +611,7 @@
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_pll_attach(dev->dvb.frontend, 0x61,
+- &dev->core->i2c_adap,
++ NULL,
+ &dvb_pll_thomson_dtt7579);
+ }
+ #endif
+@@ -623,7 +623,7 @@
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_pll_attach(dev->dvb.frontend, 0x61,
+- &dev->core->i2c_adap,
++ NULL,
+ &dvb_pll_lg_z201);
+ }
+ break;
+@@ -634,7 +634,7 @@
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_pll_attach(dev->dvb.frontend, 0x61,
+- &dev->core->i2c_adap,
++ NULL,
+ &dvb_pll_unknown_1);
+ }
+ break;
+@@ -757,7 +757,7 @@
+ &dev->core->i2c_adap);
+ if (dev->dvb.frontend != NULL) {
+ dvb_pll_attach(dev->dvb.frontend, 0x61,
+- &dev->core->i2c_adap,
++ NULL,
+ &dvb_pll_tuv1236d);
+ }
+ break;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/media/video/saa7134/saa7134-dvb.c linux-2.6.18.2-rc1/drivers/media/video/saa7134/saa7134-dvb.c
+--- linux-2.6.18.1/drivers/media/video/saa7134/saa7134-dvb.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/media/video/saa7134/saa7134-dvb.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1158,13 +1158,13 @@
+ case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
+ dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
+ if (dev->dvb.frontend) {
+- dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tdhu2);
++ dvb_pll_attach(dev->dvb.frontend, 0x61, NULL, &dvb_pll_tdhu2);
+ }
+ break;
+ case SAA7134_BOARD_KWORLD_ATSC110:
+ dev->dvb.frontend = nxt200x_attach(&kworldatsc110, &dev->i2c_adap);
+ if (dev->dvb.frontend) {
+- dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tuv1236d);
++ dvb_pll_attach(dev->dvb.frontend, 0x61, NULL, &dvb_pll_tuv1236d);
+ }
+ break;
+ #endif
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/net/sky2.c linux-2.6.18.2-rc1/drivers/net/sky2.c
+--- linux-2.6.18.1/drivers/net/sky2.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/net/sky2.c 2006-10-31 16:13:26.000000000 -0800
+@@ -678,7 +678,7 @@
+ sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+- sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
++ sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 512/8);
+ sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
+ if (hw->dev[port]->mtu > ETH_DATA_LEN) {
+ /* set Tx GMAC FIFO Almost Empty Threshold */
+@@ -690,16 +690,10 @@
+
+ }
+
+-/* Assign Ram Buffer allocation.
+- * start and end are in units of 4k bytes
+- * ram registers are in units of 64bit words
+- */
+-static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
++/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */
++static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
+ {
+- u32 start, end;
+-
+- start = startk * 4096/8;
+- end = (endk * 4096/8) - 1;
++ pr_debug(PFX "q %d %#x %#x\n", q, start, end);
+
+ sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
+ sky2_write32(hw, RB_ADDR(q, RB_START), start);
+@@ -708,7 +702,7 @@
+ sky2_write32(hw, RB_ADDR(q, RB_RP), start);
+
+ if (q == Q_R1 || q == Q_R2) {
+- u32 space = (endk - startk) * 4096/8;
++ u32 space = end - start + 1;
+ u32 tp = space - space/4;
+
+ /* On receive queue's set the thresholds
+@@ -1090,19 +1084,16 @@
+
+ sky2_mac_init(hw, port);
+
+- /* Determine available ram buffer space (in 4K blocks).
+- * Note: not sure about the FE setting below yet
+- */
+- if (hw->chip_id == CHIP_ID_YUKON_FE)
+- ramsize = 4;
+- else
+- ramsize = sky2_read8(hw, B2_E_0);
++ /* Determine available ram buffer space in qwords. */
++ ramsize = sky2_read8(hw, B2_E_0) * 4096/8;
+
+- /* Give transmitter one third (rounded up) */
+- rxspace = ramsize - (ramsize + 2) / 3;
++ if (ramsize > 6*1024/8)
++ rxspace = ramsize - (ramsize + 2) / 3;
++ else
++ rxspace = ramsize / 2;
+
+- sky2_ramset(hw, rxqaddr[port], 0, rxspace);
+- sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
++ sky2_ramset(hw, rxqaddr[port], 0, rxspace-1);
++ sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1);
+
+ /* Make sure SyncQ is disabled */
+ sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
+@@ -1429,6 +1420,11 @@
+ /* Stop more packets from being queued */
+ netif_stop_queue(dev);
+
++ /* Disable port IRQ */
++ imask = sky2_read32(hw, B0_IMSK);
++ imask &= ~portirq_msk[port];
++ sky2_write32(hw, B0_IMSK, imask);
++
+ sky2_phy_reset(hw, port);
+
+ /* Stop transmitter */
+@@ -1472,11 +1468,6 @@
+ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+ sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+
+- /* Disable port IRQ */
+- imask = sky2_read32(hw, B0_IMSK);
+- imask &= ~portirq_msk[port];
+- sky2_write32(hw, B0_IMSK, imask);
+-
+ /* turn off LED's */
+ sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+
+@@ -1687,13 +1678,13 @@
+ struct sky2_port *sky2 = netdev_priv(dev);
+ u16 istatus, phystat;
+
++ if (!netif_running(dev))
++ return;
++
+ spin_lock(&sky2->phy_lock);
+ istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
+ phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
+
+- if (!netif_running(dev))
+- goto out;
+-
+ if (netif_msg_intr(sky2))
+ printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
+ sky2->netdev->name, istatus, phystat);
+@@ -2745,6 +2736,14 @@
+ return 0;
+ }
+
++static void inline sky2_add_filter(u8 filter[8], const u8 *addr)
++{
++ u32 bit;
++
++ bit = ether_crc(ETH_ALEN, addr) & 63;
++ filter[bit >> 3] |= 1 << (bit & 7);
++}
++
+ static void sky2_set_multicast(struct net_device *dev)
+ {
+ struct sky2_port *sky2 = netdev_priv(dev);
+@@ -2753,6 +2752,7 @@
+ struct dev_mc_list *list = dev->mc_list;
+ u16 reg;
+ u8 filter[8];
++ static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };
+
+ memset(filter, 0, sizeof(filter));
+
+@@ -2763,16 +2763,17 @@
+ reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+ else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16) /* all multicast */
+ memset(filter, 0xff, sizeof(filter));
+- else if (dev->mc_count == 0) /* no multicast */
++ else if (dev->mc_count == 0 && !sky2->rx_pause)
+ reg &= ~GM_RXCR_MCF_ENA;
+ else {
+ int i;
+ reg |= GM_RXCR_MCF_ENA;
+
+- for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
+- u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
+- filter[bit / 8] |= 1 << (bit % 8);
+- }
++ if (sky2->rx_pause)
++ sky2_add_filter(filter, pause_mc_addr);
++
++ for (i = 0; list && i < dev->mc_count; i++, list = list->next)
++ sky2_add_filter(filter, list->dmi_addr);
+ }
+
+ gma_write16(hw, port, GM_MC_ADDR_H1,
+@@ -3208,6 +3209,8 @@
+ struct pci_dev *pdev = hw->pdev;
+ int err;
+
++ init_waitqueue_head (&hw->msi_wait);
++
+ sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
+
+ err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw);
+@@ -3217,18 +3220,15 @@
+ return err;
+ }
+
+- init_waitqueue_head (&hw->msi_wait);
+-
+ sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
+- wmb();
++ sky2_read8(hw, B0_CTST);
+
+ wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
+
+ if (!hw->msi_detected) {
+ /* MSI test failed, go back to INTx mode */
+- printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
+- "switching to INTx mode. Please report this failure to "
+- "the PCI maintainer and include system chipset information.\n",
++ printk(KERN_INFO PFX "%s: No interrupt generated using MSI, "
++ "switching to INTx mode.\n",
+ pci_name(pdev));
+
+ err = -EOPNOTSUPP;
+@@ -3236,6 +3236,7 @@
+ }
+
+ sky2_write32(hw, B0_IMSK, 0);
++ sky2_read32(hw, B0_IMSK);
+
+ free_irq(pdev->irq, hw);
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/net/sky2.h linux-2.6.18.2-rc1/drivers/net/sky2.h
+--- linux-2.6.18.1/drivers/net/sky2.h 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/net/sky2.h 2006-10-31 16:13:26.000000000 -0800
+@@ -1566,7 +1566,7 @@
+
+ GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
+ GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
+- GMR_FS_MII_ERR | GMR_FS_BAD_FC |
++ GMR_FS_MII_ERR | GMR_FS_GOOD_FC | GMR_FS_BAD_FC |
+ GMR_FS_UN_SIZE | GMR_FS_JABBER,
+ };
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/pci/quirks.c linux-2.6.18.2-rc1/drivers/pci/quirks.c
+--- linux-2.6.18.1/drivers/pci/quirks.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/pci/quirks.c 2006-10-31 16:13:27.000000000 -0800
+@@ -685,33 +685,6 @@
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id );
+
+-#ifdef CONFIG_ACPI_SLEEP
+-
+-/*
+- * Some VIA systems boot with the abnormal status flag set. This can cause
+- * the BIOS to re-POST the system on resume rather than passing control
+- * back to the OS. Clear the flag on boot
+- */
+-static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev)
+-{
+- u32 reg;
+-
+- acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
+- ®);
+-
+- if (reg & 0x800) {
+- printk("Clearing abnormal poweroff flag\n");
+- acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+- ACPI_REGISTER_PM1_STATUS,
+- (u16)0x800);
+- }
+-}
+-
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_abnormal_poweroff);
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_abnormal_poweroff);
+-
+-#endif
+-
+ /*
+ * CardBus controllers have a legacy base address that enables them
+ * to respond as i82365 pcmcia controllers. We don't want them to
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/rtc/rtc-max6902.c linux-2.6.18.2-rc1/drivers/rtc/rtc-max6902.c
+--- linux-2.6.18.1/drivers/rtc/rtc-max6902.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/rtc/rtc-max6902.c 2006-10-31 16:13:27.000000000 -0800
+@@ -137,7 +137,7 @@
+ dt->tm_min = BCD2BIN(chip->buf[2]);
+ dt->tm_hour = BCD2BIN(chip->buf[3]);
+ dt->tm_mday = BCD2BIN(chip->buf[4]);
+- dt->tm_mon = BCD2BIN(chip->buf[5] - 1);
++ dt->tm_mon = BCD2BIN(chip->buf[5]) - 1;
+ dt->tm_wday = BCD2BIN(chip->buf[6]);
+ dt->tm_year = BCD2BIN(chip->buf[7]);
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-2.6.18.2-rc1/drivers/scsi/aic7xxx/aic7xxx_osm.c
+--- linux-2.6.18.1/drivers/scsi/aic7xxx/aic7xxx_osm.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/scsi/aic7xxx/aic7xxx_osm.c 2006-10-31 16:13:26.000000000 -0800
+@@ -2539,15 +2539,28 @@
+ static void ahc_linux_get_signalling(struct Scsi_Host *shost)
+ {
+ struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
+- u8 mode = ahc_inb(ahc, SBLKCTL);
++ unsigned long flags;
++ u8 mode;
+
+- if (mode & ENAB40)
+- spi_signalling(shost) = SPI_SIGNAL_LVD;
+- else if (mode & ENAB20)
++ if (!(ahc->features & AHC_ULTRA2)) {
++ /* non-LVD chipset, may not have SBLKCTL reg */
+ spi_signalling(shost) =
+ ahc->features & AHC_HVD ?
+ SPI_SIGNAL_HVD :
+ SPI_SIGNAL_SE;
++ return;
++ }
++
++ ahc_lock(ahc, &flags);
++ ahc_pause(ahc);
++ mode = ahc_inb(ahc, SBLKCTL);
++ ahc_unpause(ahc);
++ ahc_unlock(ahc, &flags);
++
++ if (mode & ENAB40)
++ spi_signalling(shost) = SPI_SIGNAL_LVD;
++ else if (mode & ENAB20)
++ spi_signalling(shost) = SPI_SIGNAL_SE;
+ else
+ spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/serial/serial_core.c linux-2.6.18.2-rc1/drivers/serial/serial_core.c
+--- linux-2.6.18.1/drivers/serial/serial_core.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/serial/serial_core.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1932,6 +1932,9 @@
+ if (state->info && state->info->flags & UIF_INITIALIZED) {
+ const struct uart_ops *ops = port->ops;
+
++ state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
++ | UIF_SUSPENDED;
++
+ spin_lock_irq(&port->lock);
+ ops->stop_tx(port);
+ ops->set_mctrl(port, 0);
+@@ -1991,7 +1994,7 @@
+ console_start(port->cons);
+ }
+
+- if (state->info && state->info->flags & UIF_INITIALIZED) {
++ if (state->info && state->info->flags & UIF_SUSPENDED) {
+ const struct uart_ops *ops = port->ops;
+ int ret;
+
+@@ -2003,15 +2006,17 @@
+ ops->set_mctrl(port, port->mctrl);
+ ops->start_tx(port);
+ spin_unlock_irq(&port->lock);
++ state->info->flags |= UIF_INITIALIZED;
+ } else {
+ /*
+ * Failed to resume - maybe hardware went away?
+ * Clear the "initialized" flag so we won't try
+ * to call the low level drivers shutdown method.
+ */
+- state->info->flags &= ~UIF_INITIALIZED;
+ uart_shutdown(state);
+ }
++
++ state->info->flags &= ~UIF_SUSPENDED;
+ }
+
+ mutex_unlock(&state->mutex);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/serial/serial_cs.c linux-2.6.18.2-rc1/drivers/serial/serial_cs.c
+--- linux-2.6.18.1/drivers/serial/serial_cs.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/serial/serial_cs.c 2006-10-31 16:13:26.000000000 -0800
+@@ -185,14 +185,12 @@
+
+ static int serial_resume(struct pcmcia_device *link)
+ {
+- if (pcmcia_dev_present(link)) {
+- struct serial_info *info = link->priv;
+- int i;
++ struct serial_info *info = link->priv;
++ int i;
+
+- for (i = 0; i < info->ndev; i++)
+- serial8250_resume_port(info->line[i]);
+- wakeup_card(info);
+- }
++ for (i = 0; i < info->ndev; i++)
++ serial8250_resume_port(info->line[i]);
++ wakeup_card(info);
+
+ return 0;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/usb/core/devio.c linux-2.6.18.2-rc1/drivers/usb/core/devio.c
+--- linux-2.6.18.1/drivers/usb/core/devio.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/usb/core/devio.c 2006-10-31 16:26:56.000000000 -0800
+@@ -59,6 +59,9 @@
+ #define USB_DEVICE_MAX USB_MAXBUS * 128
+ static struct class *usb_device_class;
+
++/* Mutual exclusion for removal, open, and release */
++DEFINE_MUTEX(usbfs_mutex);
++
+ struct async {
+ struct list_head asynclist;
+ struct dev_state *ps;
+@@ -541,15 +544,13 @@
+ struct dev_state *ps;
+ int ret;
+
+- /*
+- * no locking necessary here, as chrdev_open has the kernel lock
+- * (still acquire the kernel lock for safety)
+- */
++ /* Protect against simultaneous removal or release */
++ mutex_lock(&usbfs_mutex);
++
+ ret = -ENOMEM;
+ if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
+- goto out_nolock;
++ goto out;
+
+- lock_kernel();
+ ret = -ENOENT;
+ /* check if we are called from a real node or usbfs */
+ if (imajor(inode) == USB_DEVICE_MAJOR)
+@@ -579,9 +580,8 @@
+ list_add_tail(&ps->list, &dev->filelist);
+ file->private_data = ps;
+ out:
+- unlock_kernel();
+- out_nolock:
+- return ret;
++ mutex_unlock(&usbfs_mutex);
++ return ret;
+ }
+
+ static int usbdev_release(struct inode *inode, struct file *file)
+@@ -591,7 +591,12 @@
+ unsigned int ifnum;
+
+ usb_lock_device(dev);
++
++ /* Protect against simultaneous open */
++ mutex_lock(&usbfs_mutex);
+ list_del_init(&ps->list);
++ mutex_unlock(&usbfs_mutex);
++
+ for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
+ ifnum++) {
+ if (test_bit(ifnum, &ps->ifclaimed))
+@@ -600,9 +605,8 @@
+ destroy_all_async(ps);
+ usb_unlock_device(dev);
+ usb_put_dev(dev);
+- ps->dev = NULL;
+ kfree(ps);
+- return 0;
++ return 0;
+ }
+
+ static int proc_control(struct dev_state *ps, void __user *arg)
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/usb/core/notify.c linux-2.6.18.2-rc1/drivers/usb/core/notify.c
+--- linux-2.6.18.1/drivers/usb/core/notify.c 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/usb/core/notify.c 2006-10-31 16:26:56.000000000 -0800
+@@ -50,8 +50,11 @@
+
+ void usb_notify_remove_device(struct usb_device *udev)
+ {
++ /* Protect against simultaneous usbfs open */
++ mutex_lock(&usbfs_mutex);
+ blocking_notifier_call_chain(&usb_notifier_list,
+ USB_DEVICE_REMOVE, udev);
++ mutex_unlock(&usbfs_mutex);
+ }
+
+ void usb_notify_add_bus(struct usb_bus *ubus)
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/drivers/usb/core/usb.h linux-2.6.18.2-rc1/drivers/usb/core/usb.h
+--- linux-2.6.18.1/drivers/usb/core/usb.h 2006-10-31 21:13:28.000000000 -0800
++++ linux-2.6.18.2-rc1/drivers/usb/core/usb.h 2006-10-31 16:26:56.000000000 -0800
+@@ -59,6 +59,7 @@
+ extern const char *usbcore_name;
+
+ /* usbfs stuff */
++extern struct mutex usbfs_mutex;
+ extern struct usb_driver usbfs_driver;
+ extern struct file_operations usbfs_devices_fops;
+ extern struct file_operations usbfs_device_file_operations;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/fs/fuse/dir.c linux-2.6.18.2-rc1/fs/fuse/dir.c
+--- linux-2.6.18.1/fs/fuse/dir.c 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/fs/fuse/dir.c 2006-10-31 16:13:26.000000000 -0800
+@@ -935,14 +935,30 @@
+ }
+ }
+
++static void fuse_vmtruncate(struct inode *inode, loff_t offset)
++{
++ struct fuse_conn *fc = get_fuse_conn(inode);
++ int need_trunc;
++
++ spin_lock(&fc->lock);
++ need_trunc = inode->i_size > offset;
++ i_size_write(inode, offset);
++ spin_unlock(&fc->lock);
++
++ if (need_trunc) {
++ struct address_space *mapping = inode->i_mapping;
++ unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
++ truncate_inode_pages(mapping, offset);
++ }
++}
++
+ /*
+ * Set attributes, and at the same time refresh them.
+ *
+ * Truncation is slightly complicated, because the 'truncate' request
+ * may fail, in which case we don't want to touch the mapping.
+- * vmtruncate() doesn't allow for this case. So do the rlimit
+- * checking by hand and call vmtruncate() only after the file has
+- * actually been truncated.
++ * vmtruncate() doesn't allow for this case, so do the rlimit checking
++ * and the actual truncation by hand.
+ */
+ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+ {
+@@ -993,12 +1009,8 @@
+ make_bad_inode(inode);
+ err = -EIO;
+ } else {
+- if (is_truncate) {
+- loff_t origsize = i_size_read(inode);
+- i_size_write(inode, outarg.attr.size);
+- if (origsize > outarg.attr.size)
+- vmtruncate(inode, outarg.attr.size);
+- }
++ if (is_truncate)
++ fuse_vmtruncate(inode, outarg.attr.size);
+ fuse_change_attributes(inode, &outarg.attr);
+ fi->i_time = time_to_jiffies(outarg.attr_valid,
+ outarg.attr_valid_nsec);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/fs/fuse/file.c linux-2.6.18.2-rc1/fs/fuse/file.c
+--- linux-2.6.18.1/fs/fuse/file.c 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/fs/fuse/file.c 2006-10-31 16:13:26.000000000 -0800
+@@ -481,8 +481,10 @@
+ err = -EIO;
+ if (!err) {
+ pos += count;
+- if (pos > i_size_read(inode))
++ spin_lock(&fc->lock);
++ if (pos > inode->i_size)
+ i_size_write(inode, pos);
++ spin_unlock(&fc->lock);
+
+ if (offset == 0 && to == PAGE_CACHE_SIZE) {
+ clear_page_dirty(page);
+@@ -586,8 +588,12 @@
+ }
+ fuse_put_request(fc, req);
+ if (res > 0) {
+- if (write && pos > i_size_read(inode))
+- i_size_write(inode, pos);
++ if (write) {
++ spin_lock(&fc->lock);
++ if (pos > inode->i_size)
++ i_size_write(inode, pos);
++ spin_unlock(&fc->lock);
++ }
+ *ppos = pos;
+ }
+ fuse_invalidate_attr(inode);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/fs/fuse/inode.c linux-2.6.18.2-rc1/fs/fuse/inode.c
+--- linux-2.6.18.1/fs/fuse/inode.c 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/fs/fuse/inode.c 2006-10-31 16:13:26.000000000 -0800
+@@ -109,6 +109,7 @@
+
+ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
+ {
++ struct fuse_conn *fc = get_fuse_conn(inode);
+ if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
+ invalidate_inode_pages(inode->i_mapping);
+
+@@ -117,7 +118,9 @@
+ inode->i_nlink = attr->nlink;
+ inode->i_uid = attr->uid;
+ inode->i_gid = attr->gid;
++ spin_lock(&fc->lock);
+ i_size_write(inode, attr->size);
++ spin_unlock(&fc->lock);
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_blocks = attr->blocks;
+ inode->i_atime.tv_sec = attr->atime;
+@@ -131,7 +134,7 @@
+ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
+ {
+ inode->i_mode = attr->mode & S_IFMT;
+- i_size_write(inode, attr->size);
++ inode->i_size = attr->size;
+ if (S_ISREG(inode->i_mode)) {
+ fuse_init_common(inode);
+ fuse_init_file_inode(inode);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/fs/jfs/jfs_imap.c linux-2.6.18.2-rc1/fs/jfs/jfs_imap.c
+--- linux-2.6.18.1/fs/jfs/jfs_imap.c 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/fs/jfs/jfs_imap.c 2006-10-31 16:13:26.000000000 -0800
+@@ -318,7 +318,7 @@
+ struct inomap *imap;
+ int block_offset;
+ int inodes_left;
+- uint pageno;
++ unsigned long pageno;
+ int rel_inode;
+
+ jfs_info("diRead: ino = %ld", ip->i_ino);
+@@ -606,7 +606,7 @@
+ int block_offset;
+ int inodes_left;
+ struct metapage *mp;
+- uint pageno;
++ unsigned long pageno;
+ int rel_inode;
+ int dioffset;
+ struct inode *ipimap;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/fs/nfs/dir.c linux-2.6.18.2-rc1/fs/nfs/dir.c
+--- linux-2.6.18.1/fs/nfs/dir.c 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/fs/nfs/dir.c 2006-10-31 16:13:27.000000000 -0800
+@@ -902,9 +902,15 @@
+
+ lock_kernel();
+
+- /* If we're doing an exclusive create, optimize away the lookup */
+- if (nfs_is_exclusive_create(dir, nd))
+- goto no_entry;
++ /*
++ * If we're doing an exclusive create, optimize away the lookup
++ * but don't hash the dentry.
++ */
++ if (nfs_is_exclusive_create(dir, nd)) {
++ d_instantiate(dentry, NULL);
++ res = NULL;
++ goto out_unlock;
++ }
+
+ error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
+ if (error == -ENOENT)
+@@ -1156,6 +1162,8 @@
+ if (IS_ERR(inode))
+ goto out_err;
+ d_instantiate(dentry, inode);
++ if (d_unhashed(dentry))
++ d_rehash(dentry);
+ return 0;
+ out_err:
+ d_drop(dentry);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/fs/splice.c linux-2.6.18.2-rc1/fs/splice.c
+--- linux-2.6.18.1/fs/splice.c 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/fs/splice.c 2006-10-31 16:13:26.000000000 -0800
+@@ -607,7 +607,7 @@
+ ret = -ENOMEM;
+ page = page_cache_alloc_cold(mapping);
+ if (unlikely(!page))
+- goto out_nomem;
++ goto out_ret;
+
+ /*
+ * This will also lock the page
+@@ -666,7 +666,7 @@
+ if (sd->pos + this_len > isize)
+ vmtruncate(mapping->host, isize);
+
+- goto out;
++ goto out_ret;
+ }
+
+ if (buf->page != page) {
+@@ -698,7 +698,7 @@
+ out:
+ page_cache_release(page);
+ unlock_page(page);
+-out_nomem:
++out_ret:
+ return ret;
+ }
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/include/asm-generic/audit_change_attr.h linux-2.6.18.2-rc1/include/asm-generic/audit_change_attr.h
+--- linux-2.6.18.1/include/asm-generic/audit_change_attr.h 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/include/asm-generic/audit_change_attr.h 2006-10-31 16:13:26.000000000 -0800
+@@ -1,16 +1,20 @@
+ __NR_chmod,
+ __NR_fchmod,
++#ifdef __NR_chown
+ __NR_chown,
+ __NR_fchown,
+ __NR_lchown,
++#endif
+ __NR_setxattr,
+ __NR_lsetxattr,
+ __NR_fsetxattr,
+ __NR_removexattr,
+ __NR_lremovexattr,
+ __NR_fremovexattr,
++#ifdef __NR_fchownat
+ __NR_fchownat,
+ __NR_fchmodat,
++#endif
+ #ifdef __NR_chown32
+ __NR_chown32,
+ __NR_fchown32,
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/include/asm-generic/audit_dir_write.h linux-2.6.18.2-rc1/include/asm-generic/audit_dir_write.h
+--- linux-2.6.18.1/include/asm-generic/audit_dir_write.h 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/include/asm-generic/audit_dir_write.h 2006-10-31 16:13:26.000000000 -0800
+@@ -1,14 +1,18 @@
+ __NR_rename,
+ __NR_mkdir,
+ __NR_rmdir,
++#ifdef __NR_creat
+ __NR_creat,
++#endif
+ __NR_link,
+ __NR_unlink,
+ __NR_symlink,
+ __NR_mknod,
++#ifdef __NR_mkdirat
+ __NR_mkdirat,
+ __NR_mknodat,
+ __NR_unlinkat,
+ __NR_renameat,
+ __NR_linkat,
+ __NR_symlinkat,
++#endif
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/include/asm-s390/div64.h linux-2.6.18.2-rc1/include/asm-s390/div64.h
+--- linux-2.6.18.1/include/asm-s390/div64.h 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/include/asm-s390/div64.h 2006-10-31 16:13:26.000000000 -0800
+@@ -1,49 +1 @@
+-#ifndef __S390_DIV64
+-#define __S390_DIV64
+-
+-#ifndef __s390x__
+-
+-/* for do_div "base" needs to be smaller than 2^31-1 */
+-#define do_div(n, base) ({ \
+- unsigned long long __n = (n); \
+- unsigned long __r; \
+- \
+- asm (" slr 0,0\n" \
+- " l 1,%1\n" \
+- " srdl 0,1\n" \
+- " dr 0,%2\n" \
+- " alr 1,1\n" \
+- " alr 0,0\n" \
+- " lhi 2,1\n" \
+- " n 2,%1\n" \
+- " alr 0,2\n" \
+- " clr 0,%2\n" \
+- " jl 0f\n" \
+- " slr 0,%2\n" \
+- " ahi 1,1\n" \
+- "0: st 1,%1\n" \
+- " l 1,4+%1\n" \
+- " srdl 0,1\n" \
+- " dr 0,%2\n" \
+- " alr 1,1\n" \
+- " alr 0,0\n" \
+- " lhi 2,1\n" \
+- " n 2,4+%1\n" \
+- " alr 0,2\n" \
+- " clr 0,%2\n" \
+- " jl 1f\n" \
+- " slr 0,%2\n" \
+- " ahi 1,1\n" \
+- "1: st 1,4+%1\n" \
+- " lr %0,0" \
+- : "=d" (__r), "=m" (__n) \
+- : "d" (base), "m" (__n) : "0", "1", "2", "cc" ); \
+- (n) = (__n); \
+- __r; \
+-})
+-
+-#else /* __s390x__ */
+ #include <asm-generic/div64.h>
+-#endif /* __s390x__ */
+-
+-#endif
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/include/linux/mmzone.h linux-2.6.18.2-rc1/include/linux/mmzone.h
+--- linux-2.6.18.1/include/linux/mmzone.h 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/include/linux/mmzone.h 2006-10-31 16:13:27.000000000 -0800
+@@ -200,13 +200,9 @@
+ * under - it drives the swappiness decision: whether to unmap mapped
+ * pages.
+ *
+- * temp_priority is used to remember the scanning priority at which
+- * this zone was successfully refilled to free_pages == pages_high.
+- *
+- * Access to both these fields is quite racy even on uniprocessor. But
++ * Access to both this field is quite racy even on uniprocessor. But
+ * it is expected to average out OK.
+ */
+- int temp_priority;
+ int prev_priority;
+
+
+@@ -632,6 +628,12 @@
+ #define sparse_index_init(_sec, _nid) do {} while (0)
+ #endif /* CONFIG_SPARSEMEM */
+
++#ifdef CONFIG_NODES_SPAN_OTHER_NODES
++#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
++#else
++#define early_pfn_in_nid(pfn, nid) (1)
++#endif
++
+ #ifndef early_pfn_valid
+ #define early_pfn_valid(pfn) (1)
+ #endif
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/include/linux/serial_core.h linux-2.6.18.2-rc1/include/linux/serial_core.h
+--- linux-2.6.18.1/include/linux/serial_core.h 2006-10-31 21:13:29.000000000 -0800
++++ linux-2.6.18.2-rc1/include/linux/serial_core.h 2006-10-31 16:13:26.000000000 -0800
+@@ -319,6 +319,7 @@
+ #define UIF_CTS_FLOW ((__force uif_t) (1 << 26))
+ #define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29))
+ #define UIF_INITIALIZED ((__force uif_t) (1 << 31))
++#define UIF_SUSPENDED ((__force uif_t) (1 << 30))
+
+ int blocked_open;
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/kernel/posix-cpu-timers.c linux-2.6.18.2-rc1/kernel/posix-cpu-timers.c
+--- linux-2.6.18.1/kernel/posix-cpu-timers.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/kernel/posix-cpu-timers.c 2006-10-31 16:13:26.000000000 -0800
+@@ -88,6 +88,19 @@
+ }
+
+ /*
++ * Divide and limit the result to res >= 1
++ *
++ * This is necessary to prevent signal delivery starvation, when the result of
++ * the division would be rounded down to 0.
++ */
++static inline cputime_t cputime_div_non_zero(cputime_t time, unsigned long div)
++{
++ cputime_t res = cputime_div(time, div);
++
++ return max_t(cputime_t, res, 1);
++}
++
++/*
+ * Update expiry time from increment, and increase overrun count,
+ * given the current clock sample.
+ */
+@@ -483,8 +496,8 @@
+ BUG();
+ break;
+ case CPUCLOCK_PROF:
+- left = cputime_div(cputime_sub(expires.cpu, val.cpu),
+- nthreads);
++ left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
++ nthreads);
+ do {
+ if (likely(!(t->flags & PF_EXITING))) {
+ ticks = cputime_add(prof_ticks(t), left);
+@@ -498,8 +511,8 @@
+ } while (t != p);
+ break;
+ case CPUCLOCK_VIRT:
+- left = cputime_div(cputime_sub(expires.cpu, val.cpu),
+- nthreads);
++ left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
++ nthreads);
+ do {
+ if (likely(!(t->flags & PF_EXITING))) {
+ ticks = cputime_add(virt_ticks(t), left);
+@@ -515,6 +528,7 @@
+ case CPUCLOCK_SCHED:
+ nsleft = expires.sched - val.sched;
+ do_div(nsleft, nthreads);
++ nsleft = max_t(unsigned long long, nsleft, 1);
+ do {
+ if (likely(!(t->flags & PF_EXITING))) {
+ ns = t->sched_time + nsleft;
+@@ -1159,12 +1173,13 @@
+
+ prof_left = cputime_sub(prof_expires, utime);
+ prof_left = cputime_sub(prof_left, stime);
+- prof_left = cputime_div(prof_left, nthreads);
++ prof_left = cputime_div_non_zero(prof_left, nthreads);
+ virt_left = cputime_sub(virt_expires, utime);
+- virt_left = cputime_div(virt_left, nthreads);
++ virt_left = cputime_div_non_zero(virt_left, nthreads);
+ if (sched_expires) {
+ sched_left = sched_expires - sched_time;
+ do_div(sched_left, nthreads);
++ sched_left = max_t(unsigned long long, sched_left, 1);
+ } else {
+ sched_left = 0;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/kernel/taskstats.c linux-2.6.18.2-rc1/kernel/taskstats.c
+--- linux-2.6.18.1/kernel/taskstats.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/kernel/taskstats.c 2006-10-31 16:13:27.000000000 -0800
+@@ -229,14 +229,17 @@
+ } else
+ get_task_struct(first);
+
+- /* Start with stats from dead tasks */
+- spin_lock_irqsave(&first->signal->stats_lock, flags);
+- if (first->signal->stats)
+- memcpy(stats, first->signal->stats, sizeof(*stats));
+- spin_unlock_irqrestore(&first->signal->stats_lock, flags);
+
+ tsk = first;
+ read_lock(&tasklist_lock);
++ /* Start with stats from dead tasks */
++ if (first->signal) {
++ spin_lock_irqsave(&first->signal->stats_lock, flags);
++ if (first->signal->stats)
++ memcpy(stats, first->signal->stats, sizeof(*stats));
++ spin_unlock_irqrestore(&first->signal->stats_lock, flags);
++ }
++
+ do {
+ if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk))
+ continue;
+@@ -256,7 +259,7 @@
+ * Accounting subsytems can also add calls here to modify
+ * fields of taskstats.
+ */
+-
++ put_task_struct(first);
+ return 0;
+ }
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/lib/audit.c linux-2.6.18.2-rc1/lib/audit.c
+--- linux-2.6.18.1/lib/audit.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/lib/audit.c 2006-10-31 16:13:26.000000000 -0800
+@@ -28,8 +28,10 @@
+ switch(syscall) {
+ case __NR_open:
+ return 2;
++#ifdef __NR_openat
+ case __NR_openat:
+ return 3;
++#endif
+ #ifdef __NR_socketcall
+ case __NR_socketcall:
+ return 4;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/mm/memory.c linux-2.6.18.2-rc1/mm/memory.c
+--- linux-2.6.18.1/mm/memory.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/mm/memory.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1551,7 +1551,14 @@
+ entry = mk_pte(new_page, vma->vm_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ lazy_mmu_prot_update(entry);
+- ptep_establish(vma, address, page_table, entry);
++ /*
++ * Clear the pte entry and flush it first, before updating the
++ * pte with the new entry. This will avoid a race condition
++ * seen in the presence of one thread doing SMC and another
++ * thread doing COW.
++ */
++ ptep_clear_flush(vma, address, page_table);
++ set_pte_at(mm, address, page_table, entry);
+ update_mmu_cache(vma, address, entry);
+ lru_cache_add_active(new_page);
+ page_add_new_anon_rmap(new_page, vma, address);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/mm/page_alloc.c linux-2.6.18.2-rc1/mm/page_alloc.c
+--- linux-2.6.18.1/mm/page_alloc.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/mm/page_alloc.c 2006-10-31 16:13:27.000000000 -0800
+@@ -1673,6 +1673,8 @@
+ for (pfn = start_pfn; pfn < end_pfn; pfn++) {
+ if (!early_pfn_valid(pfn))
+ continue;
++ if (!early_pfn_in_nid(pfn, nid))
++ continue;
+ page = pfn_to_page(pfn);
+ set_page_links(page, zone, nid, pfn);
+ init_page_count(page);
+@@ -2019,7 +2021,7 @@
+ zone->zone_pgdat = pgdat;
+ zone->free_pages = 0;
+
+- zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
++ zone->prev_priority = DEF_PRIORITY;
+
+ zone_pcp_init(zone);
+ INIT_LIST_HEAD(&zone->active_list);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/mm/vmscan.c linux-2.6.18.2-rc1/mm/vmscan.c
+--- linux-2.6.18.1/mm/vmscan.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/mm/vmscan.c 2006-10-31 16:13:27.000000000 -0800
+@@ -696,6 +696,20 @@
+ }
+
+ /*
++ * We are about to scan this zone at a certain priority level. If that priority
++ * level is smaller (ie: more urgent) than the previous priority, then note
++ * that priority level within the zone. This is done so that when the next
++ * process comes in to scan this zone, it will immediately start out at this
++ * priority level rather than having to build up its own scanning priority.
++ * Here, this priority affects only the reclaim-mapped threshold.
++ */
++static inline void note_zone_scanning_priority(struct zone *zone, int priority)
++{
++ if (priority < zone->prev_priority)
++ zone->prev_priority = priority;
++}
++
++/*
+ * This moves pages from the active list to the inactive list.
+ *
+ * We move them the other way if the page is referenced by one or more
+@@ -713,7 +727,7 @@
+ * But we had to alter page->flags anyway.
+ */
+ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
+- struct scan_control *sc)
++ struct scan_control *sc, int priority)
+ {
+ unsigned long pgmoved;
+ int pgdeactivate = 0;
+@@ -734,7 +748,7 @@
+ * `distress' is a measure of how much trouble we're having
+ * reclaiming pages. 0 -> no problems. 100 -> great trouble.
+ */
+- distress = 100 >> zone->prev_priority;
++ distress = 100 >> min(zone->prev_priority, priority);
+
+ /*
+ * The point of this algorithm is to decide when to start
+@@ -885,7 +899,7 @@
+ nr_to_scan = min(nr_active,
+ (unsigned long)sc->swap_cluster_max);
+ nr_active -= nr_to_scan;
+- shrink_active_list(nr_to_scan, zone, sc);
++ shrink_active_list(nr_to_scan, zone, sc, priority);
+ }
+
+ if (nr_inactive) {
+@@ -934,9 +948,7 @@
+ if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+ continue;
+
+- zone->temp_priority = priority;
+- if (zone->prev_priority > priority)
+- zone->prev_priority = priority;
++ note_zone_scanning_priority(zone, priority);
+
+ if (zone->all_unreclaimable && priority != DEF_PRIORITY)
+ continue; /* Let kswapd poll it */
+@@ -984,7 +996,6 @@
+ if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+ continue;
+
+- zone->temp_priority = DEF_PRIORITY;
+ lru_pages += zone->nr_active + zone->nr_inactive;
+ }
+
+@@ -1022,13 +1033,22 @@
+ blk_congestion_wait(WRITE, HZ/10);
+ }
+ out:
++ /*
++ * Now that we've scanned all the zones at this priority level, note
++ * that level within the zone so that the next thread which performs
++ * scanning of this zone will immediately start out at this priority
++ * level. This affects only the decision whether or not to bring
++ * mapped pages onto the inactive list.
++ */
++ if (priority < 0)
++ priority = 0;
+ for (i = 0; zones[i] != 0; i++) {
+ struct zone *zone = zones[i];
+
+ if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+ continue;
+
+- zone->prev_priority = zone->temp_priority;
++ zone->prev_priority = priority;
+ }
+ return ret;
+ }
+@@ -1068,6 +1088,11 @@
+ .swap_cluster_max = SWAP_CLUSTER_MAX,
+ .swappiness = vm_swappiness,
+ };
++ /*
++ * temp_priority is used to remember the scanning priority at which
++ * this zone was successfully refilled to free_pages == pages_high.
++ */
++ int temp_priority[MAX_NR_ZONES];
+
+ loop_again:
+ total_scanned = 0;
+@@ -1075,11 +1100,8 @@
+ sc.may_writepage = !laptop_mode;
+ count_vm_event(PAGEOUTRUN);
+
+- for (i = 0; i < pgdat->nr_zones; i++) {
+- struct zone *zone = pgdat->node_zones + i;
+-
+- zone->temp_priority = DEF_PRIORITY;
+- }
++ for (i = 0; i < pgdat->nr_zones; i++)
++ temp_priority[i] = DEF_PRIORITY;
+
+ for (priority = DEF_PRIORITY; priority >= 0; priority--) {
+ int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */
+@@ -1140,10 +1162,9 @@
+ if (!zone_watermark_ok(zone, order, zone->pages_high,
+ end_zone, 0))
+ all_zones_ok = 0;
+- zone->temp_priority = priority;
+- if (zone->prev_priority > priority)
+- zone->prev_priority = priority;
++ temp_priority[i] = priority;
+ sc.nr_scanned = 0;
++ note_zone_scanning_priority(zone, priority);
+ nr_reclaimed += shrink_zone(priority, zone, &sc);
+ reclaim_state->reclaimed_slab = 0;
+ nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
+@@ -1183,10 +1204,15 @@
+ break;
+ }
+ out:
++ /*
++ * Note within each zone the priority level at which this zone was
++ * brought into a happy state. So that the next thread which scans this
++ * zone will start out at that priority level.
++ */
+ for (i = 0; i < pgdat->nr_zones; i++) {
+ struct zone *zone = pgdat->node_zones + i;
+
+- zone->prev_priority = zone->temp_priority;
++ zone->prev_priority = temp_priority[i];
+ }
+ if (!all_zones_ok) {
+ cond_resched();
+@@ -1315,7 +1341,7 @@
+ if (zone->nr_scan_active >= nr_pages || pass > 3) {
+ zone->nr_scan_active = 0;
+ nr_to_scan = min(nr_pages, zone->nr_active);
+- shrink_active_list(nr_to_scan, zone, sc);
++ shrink_active_list(nr_to_scan, zone, sc, prio);
+ }
+ }
+
+@@ -1570,6 +1596,7 @@
+ */
+ priority = ZONE_RECLAIM_PRIORITY;
+ do {
++ note_zone_scanning_priority(zone, priority);
+ nr_reclaimed += shrink_zone(priority, zone, &sc);
+ priority--;
+ } while (priority >= 0 && nr_reclaimed < nr_pages);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/mm/vmstat.c linux-2.6.18.2-rc1/mm/vmstat.c
+--- linux-2.6.18.1/mm/vmstat.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/mm/vmstat.c 2006-10-31 16:13:27.000000000 -0800
+@@ -586,11 +586,9 @@
+ seq_printf(m,
+ "\n all_unreclaimable: %u"
+ "\n prev_priority: %i"
+- "\n temp_priority: %i"
+ "\n start_pfn: %lu",
+ zone->all_unreclaimable,
+ zone->prev_priority,
+- zone->temp_priority,
+ zone->zone_start_pfn);
+ spin_unlock_irqrestore(&zone->lock, flags);
+ seq_putc(m, '\n');
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/net/bluetooth/rfcomm/tty.c linux-2.6.18.2-rc1/net/bluetooth/rfcomm/tty.c
+--- linux-2.6.18.1/net/bluetooth/rfcomm/tty.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/net/bluetooth/rfcomm/tty.c 2006-10-31 16:13:26.000000000 -0800
+@@ -748,6 +748,9 @@
+
+ BT_DBG("tty %p termios %p", tty, old);
+
++ if (!dev)
++ return;
++
+ /* Handle turning off CRTSCTS */
+ if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
+ BT_DBG("Turning off CRTSCTS unsupported");
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/net/core/skbuff.c linux-2.6.18.2-rc1/net/core/skbuff.c
+--- linux-2.6.18.1/net/core/skbuff.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/net/core/skbuff.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1945,7 +1945,7 @@
+ do {
+ struct sk_buff *nskb;
+ skb_frag_t *frag;
+- int hsize, nsize;
++ int hsize;
+ int k;
+ int size;
+
+@@ -1956,11 +1956,10 @@
+ hsize = skb_headlen(skb) - offset;
+ if (hsize < 0)
+ hsize = 0;
+- nsize = hsize + doffset;
+- if (nsize > len + doffset || !sg)
+- nsize = len + doffset;
++ if (hsize > len || !sg)
++ hsize = len;
+
+- nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
++ nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
+ if (unlikely(!nskb))
+ goto err;
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/net/decnet/af_decnet.c linux-2.6.18.2-rc1/net/decnet/af_decnet.c
+--- linux-2.6.18.1/net/decnet/af_decnet.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/net/decnet/af_decnet.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1177,8 +1177,10 @@
+ if (peer) {
+ if ((sock->state != SS_CONNECTED &&
+ sock->state != SS_CONNECTING) &&
+- scp->accept_mode == ACC_IMMED)
++ scp->accept_mode == ACC_IMMED) {
++ release_sock(sk);
+ return -ENOTCONN;
++ }
+
+ memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn));
+ } else {
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/net/ipv4/tcp_cubic.c linux-2.6.18.2-rc1/net/ipv4/tcp_cubic.c
+--- linux-2.6.18.1/net/ipv4/tcp_cubic.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/net/ipv4/tcp_cubic.c 2006-10-31 16:13:27.000000000 -0800
+@@ -190,7 +190,7 @@
+ */
+
+ /* change the unit from HZ to bictcp_HZ */
+- t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start)
++ t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start)
+ << BICTCP_HZ) / HZ;
+
+ if (t < ca->bic_K) /* t - K */
+@@ -259,7 +259,7 @@
+ (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
+ return;
+
+- delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
++ delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3;
+ if (delay == 0)
+ delay = 1;
+
+@@ -366,7 +366,7 @@
+
+ beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta);
+
+- cube_rtt_scale = (bic_scale << 3) / 10; /* 1024*c/rtt */
++ cube_rtt_scale = (bic_scale * 10); /* 1024*c/rtt */
+
+ /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
+ * so K = cubic_root( (wmax-cwnd)*rtt/c )
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/net/ipv6/ip6_flowlabel.c linux-2.6.18.2-rc1/net/ipv6/ip6_flowlabel.c
+--- linux-2.6.18.1/net/ipv6/ip6_flowlabel.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/net/ipv6/ip6_flowlabel.c 2006-10-31 16:13:27.000000000 -0800
+@@ -587,6 +587,8 @@
+ while (!fl) {
+ if (++state->bucket <= FL_HASH_MASK)
+ fl = fl_ht[state->bucket];
++ else
++ break;
+ }
+ return fl;
+ }
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/net/sctp/input.c linux-2.6.18.2-rc1/net/sctp/input.c
+--- linux-2.6.18.1/net/sctp/input.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/net/sctp/input.c 2006-10-31 16:13:26.000000000 -0800
+@@ -135,6 +135,9 @@
+
+ SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS);
+
++ if (skb_linearize(skb))
++ goto discard_it;
++
+ sh = (struct sctphdr *) skb->h.raw;
+
+ /* Pull up the IP and SCTP headers. */
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/net/sunrpc/svcsock.c linux-2.6.18.2-rc1/net/sunrpc/svcsock.c
+--- linux-2.6.18.1/net/sunrpc/svcsock.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/net/sunrpc/svcsock.c 2006-10-31 16:13:26.000000000 -0800
+@@ -902,7 +902,7 @@
+ return 0;
+ }
+
+- if (test_bit(SK_CONN, &svsk->sk_flags)) {
++ if (svsk->sk_sk->sk_state == TCP_LISTEN) {
+ svc_tcp_accept(svsk);
+ svc_sock_received(svsk);
+ return 0;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/core/hwdep.c linux-2.6.18.2-rc1/sound/core/hwdep.c
+--- linux-2.6.18.1/sound/core/hwdep.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/core/hwdep.c 2006-10-31 16:13:26.000000000 -0800
+@@ -158,6 +158,7 @@
+ {
+ int err = -ENXIO;
+ struct snd_hwdep *hw = file->private_data;
++ struct module *mod = hw->card->module;
+ mutex_lock(&hw->open_mutex);
+ if (hw->ops.release) {
+ err = hw->ops.release(hw, file);
+@@ -167,7 +168,7 @@
+ hw->used--;
+ snd_card_file_remove(hw->card, file);
+ mutex_unlock(&hw->open_mutex);
+- module_put(hw->card->module);
++ module_put(mod);
+ return err;
+ }
+
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/core/info.c linux-2.6.18.2-rc1/sound/core/info.c
+--- linux-2.6.18.1/sound/core/info.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/core/info.c 2006-10-31 16:13:26.000000000 -0800
+@@ -119,7 +119,10 @@
+ len = buffer->len - buffer->size;
+ va_start(args, fmt);
+ for (;;) {
+- res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
++ va_list ap;
++ va_copy(ap, args);
++ res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, ap);
++ va_end(ap);
+ if (res < len)
+ break;
+ err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/core/rtctimer.c linux-2.6.18.2-rc1/sound/core/rtctimer.c
+--- linux-2.6.18.1/sound/core/rtctimer.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/core/rtctimer.c 2006-10-31 16:13:26.000000000 -0800
+@@ -50,7 +50,9 @@
+ * The hardware dependent description for this timer.
+ */
+ static struct snd_timer_hardware rtc_hw = {
+- .flags = SNDRV_TIMER_HW_FIRST|SNDRV_TIMER_HW_AUTO,
++ .flags = SNDRV_TIMER_HW_AUTO |
++ SNDRV_TIMER_HW_FIRST |
++ SNDRV_TIMER_HW_TASKLET,
+ .ticks = 100000000L, /* FIXME: XXX */
+ .open = rtctimer_open,
+ .close = rtctimer_close,
+@@ -60,6 +62,7 @@
+
+ static int rtctimer_freq = RTC_FREQ; /* frequency */
+ static struct snd_timer *rtctimer;
++static struct tasklet_struct rtc_tasklet;
+ static rtc_task_t rtc_task;
+
+
+@@ -81,6 +84,7 @@
+ rtc_task_t *rtc = t->private_data;
+ if (rtc) {
+ rtc_unregister(rtc);
++ tasklet_kill(&rtc_tasklet);
+ t->private_data = NULL;
+ }
+ return 0;
+@@ -105,12 +109,17 @@
+ return 0;
+ }
+
++static void rtctimer_tasklet(unsigned long data)
++{
++ snd_timer_interrupt((struct snd_timer *)data, 1);
++}
++
+ /*
+ * interrupt
+ */
+ static void rtctimer_interrupt(void *private_data)
+ {
+- snd_timer_interrupt(private_data, 1);
++ tasklet_hi_schedule(private_data);
+ }
+
+
+@@ -139,9 +148,11 @@
+ timer->hw = rtc_hw;
+ timer->hw.resolution = NANO_SEC / rtctimer_freq;
+
++ tasklet_init(&rtc_tasklet, rtctimer_tasklet, (unsigned long)timer);
++
+ /* set up RTC callback */
+ rtc_task.func = rtctimer_interrupt;
+- rtc_task.private_data = timer;
++ rtc_task.private_data = &rtc_tasklet;
+
+ err = snd_timer_global_register(timer);
+ if (err < 0) {
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/pci/au88x0/au88x0.c linux-2.6.18.2-rc1/sound/pci/au88x0/au88x0.c
+--- linux-2.6.18.1/sound/pci/au88x0/au88x0.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/pci/au88x0/au88x0.c 2006-10-31 16:13:26.000000000 -0800
+@@ -128,6 +128,7 @@
+ // Take down PCI interface.
+ synchronize_irq(vortex->irq);
+ free_irq(vortex->irq, vortex);
++ iounmap(vortex->mmio);
+ pci_release_regions(vortex->pci_dev);
+ pci_disable_device(vortex->pci_dev);
+ kfree(vortex);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/pci/emu10k1/emu10k1_main.c linux-2.6.18.2-rc1/sound/pci/emu10k1/emu10k1_main.c
+--- linux-2.6.18.1/sound/pci/emu10k1/emu10k1_main.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/pci/emu10k1/emu10k1_main.c 2006-10-31 16:13:26.000000000 -0800
+@@ -1460,8 +1460,8 @@
+
+ /* resore for spdif */
+ if (emu->audigy)
+- outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
+- outl(emu->port + HCFG, emu->saved_hcfg);
++ outl(emu->saved_a_iocfg, emu->port + A_IOCFG);
++ outl(emu->saved_hcfg, emu->port + HCFG);
+
+ val = emu->saved_ptr;
+ for (reg = saved_regs; *reg != 0xff; reg++)
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/ppc/keywest.c linux-2.6.18.2-rc1/sound/ppc/keywest.c
+--- linux-2.6.18.1/sound/ppc/keywest.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/ppc/keywest.c 2006-10-31 16:13:26.000000000 -0800
+@@ -117,6 +117,9 @@
+ {
+ int err;
+
++ if (!keywest_ctx || !keywest_ctx->client)
++ return -ENXIO;
++
+ if ((err = keywest_ctx->init_client(keywest_ctx)) < 0) {
+ snd_printk(KERN_ERR "tumbler: %i :cannot initialize the MCS\n", err);
+ return err;
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/usb/usx2y/usbusx2yaudio.c linux-2.6.18.2-rc1/sound/usb/usx2y/usbusx2yaudio.c
+--- linux-2.6.18.1/sound/usb/usx2y/usbusx2yaudio.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/usb/usx2y/usbusx2yaudio.c 2006-10-31 16:13:26.000000000 -0800
+@@ -322,7 +322,7 @@
+ usX2Y_error_urb_status(usX2Y, subs, urb);
+ return;
+ }
+- if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
++ if (likely(urb->start_frame == usX2Y->wait_iso_frame))
+ subs->completed_urb = urb;
+ else {
+ usX2Y_error_sequence(usX2Y, subs, urb);
+@@ -335,13 +335,9 @@
+ atomic_read(&capsubs->state) >= state_PREPARED &&
+ (playbacksubs->completed_urb ||
+ atomic_read(&playbacksubs->state) < state_PREPARED)) {
+- if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
+- if (nr_of_packs() <= urb->start_frame &&
+- urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci
+- usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
+- else
+- usX2Y->wait_iso_frame += nr_of_packs();
+- } else {
++ if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
++ usX2Y->wait_iso_frame += nr_of_packs();
++ else {
+ snd_printdd("\n");
+ usX2Y_clients_stop(usX2Y);
+ }
+@@ -495,7 +491,6 @@
+ if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
+ goto start;
+ }
+- usX2Y->wait_iso_frame = -1;
+
+ start:
+ usX2Y_subs_startup(subs);
+@@ -516,10 +511,9 @@
+ snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
+ err = -EPIPE;
+ goto cleanup;
+- } else {
+- if (0 > usX2Y->wait_iso_frame)
++ } else
++ if (i == 0)
+ usX2Y->wait_iso_frame = urb->start_frame;
+- }
+ urb->transfer_flags = 0;
+ } else {
+ atomic_set(&subs->state, state_STARTING1);
+diff -Naur -X /home/chrisw/dontdiff linux-2.6.18.1/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.18.2-rc1/sound/usb/usx2y/usx2yhwdeppcm.c
+--- linux-2.6.18.1/sound/usb/usx2y/usx2yhwdeppcm.c 2006-10-31 21:13:30.000000000 -0800
++++ linux-2.6.18.2-rc1/sound/usb/usx2y/usx2yhwdeppcm.c 2006-10-31 16:13:26.000000000 -0800
+@@ -243,7 +243,7 @@
+ usX2Y_error_urb_status(usX2Y, subs, urb);
+ return;
+ }
+- if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
++ if (likely(urb->start_frame == usX2Y->wait_iso_frame))
+ subs->completed_urb = urb;
+ else {
+ usX2Y_error_sequence(usX2Y, subs, urb);
+@@ -256,13 +256,9 @@
+ if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
+ (NULL == capsubs2 || capsubs2->completed_urb) &&
+ (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
+- if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) {
+- if (nr_of_packs() <= urb->start_frame &&
+- urb->start_frame <= (2 * nr_of_packs() - 1)) // uhci and ohci
+- usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
+- else
+- usX2Y->wait_iso_frame += nr_of_packs();
+- } else {
++ if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
++ usX2Y->wait_iso_frame += nr_of_packs();
++ else {
+ snd_printdd("\n");
+ usX2Y_clients_stop(usX2Y);
+ }
+@@ -433,7 +429,6 @@
+ if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
+ goto start;
+ }
+- usX2Y->wait_iso_frame = -1;
+
+ start:
+ usX2Y_usbpcm_subs_startup(subs);
+@@ -459,7 +454,7 @@
+ goto cleanup;
+ } else {
+ snd_printdd("%i\n", urb->start_frame);
+- if (0 > usX2Y->wait_iso_frame)
++ if (u == 0)
+ usX2Y->wait_iso_frame = urb->start_frame;
+ }
+ urb->transfer_flags = 0;
+@@ -632,7 +627,7 @@
+ for (s = 0; s < 2; ++s) {
+ struct snd_pcm_substream *substream;
+ substream = pcm->streams[s].substream;
+- if (SUBSTREAM_BUSY(substream))
++ if (substream && SUBSTREAM_BUSY(substream))
+ err = -EBUSY;
+ }
+ }
Modified: dists/trunk/linux-2.6/debian/patches/series/4
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/4 (original)
+++ dists/trunk/linux-2.6/debian/patches/series/4 Thu Nov 2 18:50:36 2006
@@ -1,20 +1,22 @@
+- bugfix/serial_cs-resume.patch
+- bugfix/serial_core-suspend_oops.patch
+- bugfix/dac960_ipr_pci_clash.patch
- sparc64-atyfb-xl-gr.patch
-+ bugfix/sparc/sunblade-clock-hang.patch
+- bugfix/bluetooth_rfcomm_oops.patch
+- bugfix/via_pmu_backlight-fix_panic_sleep.patch
+- bugfix/sky2-receive-FIFO-fix.patch
+ bugfix/sparc/compat-alloc-user-space-alignment.patch
+ bugfix/arm/n2100-serial-irq.patch
+ bugfix/arm/n2100-eth1-irq.patch
+ bugfix/sparc/bus-id-size.patch
+ bugfix/net-netpoll.patch
-+ bugfix/net-sky2-lockup.patch
+ features/net-forcedeth-swsusp.patch
+ bugfix/net-r8169-mmio8167.patch
+ features/net-r8169-pci_id-corega.patch
+ bugfix/net-r8169-hotplug_loop.patch
+ bugfix/arm/arm-generic-time.patch
+ bugfix/arm/ixp4xx-clocksource.patch
-+ bugfix/audit-syscalls.patch
+ bugfix/net-r8169-no_mac_adress_change.patch
-+ bugfix/x86-64-c3_timer.patch
+ features/arm/nslu2-setup-mac.patch
+ features/arm/nslu2-eth-mac.patch
+ features/arm/ixp4xx-0.2.1-driver.patch
@@ -22,7 +24,6 @@
+ features/arm/ixp4xx-net-driver-improve-mac-handling.patch
+ bugfix/powerpc/interrupt-alignement.patch
+ bugfix/sparc/sunblade1k-boot-fix.patch
-+ bugfix/__div64_32-for-31-bit.patch
+ bugfix/net-bcm43xx_netdev_watchdog.patch
+ bugfix/copy-user-highpage.patch
- mips-sb1-duart-tts.patch
@@ -42,3 +43,4 @@
+ features/mips/backtrace.patch
+ features/fintek-f75375.patch
+ bugfix/sparc/t1k-cpu-lockup.patch
++ bugfix/2.6.18.2
More information about the Kernel-svn-changes
mailing list