[kernel] r8969 - in dists/sid/linux-2.6/debian: . patches/bugfix patches/series
Maximilian Attems
maks at alioth.debian.org
Mon Jun 11 22:17:49 UTC 2007
Author: maks
Date: Mon Jun 11 22:17:49 2007
New Revision: 8969
Log:
add huge stable 2.6.21.5
Added:
dists/sid/linux-2.6/debian/patches/bugfix/2.6.21.5
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/5
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog (original)
+++ dists/sid/linux-2.6/debian/changelog Mon Jun 11 22:17:49 2007
@@ -10,8 +10,63 @@
- random: fix seeding with zero entropy (CVE-2007-2453 2 of 2)
- NETFILTER: {ip, nf}_conntrack_sctp: fix remotely triggerable NULL ptr
dereference (CVE-2007-2876)
+ * Add stable release 2.6.21.5:
+ - acpi: fix potential call to a freed memory section.
+ - USB: set the correct Interrupt interval in usb_bulk_msg
+ - i386: Fix K8/core2 oprofile on multiple CPUs
+ - ntfs_init_locked_inode(): fix array indexing
+ - ALSA: wm8750 typo fix
+ - neofb: Fix pseudo_palette array overrun in neofb_setcolreg
+ - e1000: disable polling before registering netdevice
+ - timer statistics: fix race
+ - x86: fix oprofile double free
+ - ALSA: usb-audio: explicitly match Logitech QuickCam
+ - zd1211rw: Add AL2230S RF support
+ - IPV4: Correct rp_filter help text.
+ - Fix AF_UNIX OOPS
+ - ICMP: Fix icmp_errors_use_inbound_ifaddr sysctl
+ - NET: Fix BMSR_100{HALF,FULL}2 defines in linux/mii.h
+ - SPARC64: Fix _PAGE_EXEC_4U check in sun4u I-TLB miss handler.
+ - SPARC64: Don't be picky about virtual-dma values on sun4v.
+ - SPARC64: Fix two bugs wrt. kernel 4MB TSB.
+ - cciss: fix pci_driver.shutdown while device is still active
+ - fix compat console unimap regression
+ - timer stats: speedups
+ - SPARC: Linux always started with 9600 8N1
+ - pci_ids: update patch for Intel ICH9M
+ - PCI: quirk disable MSI on via vt3351
+ - UML - Improve host PTRACE_SYSEMU check
+ - NET: parse ip:port strings correctly in in4_pton
+ - Char: cyclades, fix deadlock
+ - IPSEC: Fix panic when using inter address familiy IPsec on loopback.
+ - TCP: Use default 32768-61000 outgoing port range in all cases.
+ - TG3: Fix link problem on Dell's onboard 5906.
+ - fuse: fix mknod of regular file
+ - md: Avoid overflow in raid0 calculation with large components.
+ - md: Don't write more than is required of the last page of a bitmap
+ - make freezeable workqueues singlethread
+ - tty: fix leakage of -ERESTARTSYS to userland
+ - V4L/DVB (5593): Budget-ci: Fix tuning for TDM 1316 (160..200 MHz)
+ - Input: i8042 - fix AUX port detection with some chips
+ - SCSI: aacraid: Correct sa platform support.
+ (Was: [Bug 8469] Bad EIP value on pentium3 SMP kernel-2.6.21.1)
+ - BLUETOOTH: Fix locking in hci_sock_dev_event().
+ - hpt366: don't check enablebits for HPT36x
+ - ieee1394: eth1394: bring back a parent device
+ - NET: Fix race condition about network device name allocation.
+ - ALSA: hda-intel - Probe additional slots only if necessary
+ - ALSA: hda-intel - Fix detection of audio codec on Toshiba A100
+ - ahci: disable 64bit dma on sb600
+ - i386: HPET, check if the counter works
+ - Ignore bogus ACPI info for offline CPUs
+ - NOHZ: Rate limit the local softirq pending warning output
+ - Prevent going idle with softirq pending
+ - Work around Dell E520 BIOS reboot bug
+ - NET: "wrong timeout value" in sk_wait_data() v2
+ - IPV6 ROUTE: No longer handle ::/0 specially.
+ - x86_64: allocate sparsemem memmap above 4G
- -- maximilian attems <maks at debian.org> Fri, 08 Jun 2007 16:32:36 +0200
+ -- maximilian attems <maks at debian.org> Tue, 12 Jun 2007 00:14:13 +0200
linux-2.6 (2.6.21-4) unstable; urgency=low
Added: dists/sid/linux-2.6/debian/patches/bugfix/2.6.21.5
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/bugfix/2.6.21.5 Mon Jun 11 22:17:49 2007
@@ -0,0 +1,2372 @@
+diff --git a/Documentation/hrtimer/timer_stats.txt b/Documentation/hrtimer/timer_stats.txt
+index 27f782e..22b0814 100644
+--- a/Documentation/hrtimer/timer_stats.txt
++++ b/Documentation/hrtimer/timer_stats.txt
+@@ -2,9 +2,10 @@ timer_stats - timer usage statistics
+ ------------------------------------
+
+ timer_stats is a debugging facility to make the timer (ab)usage in a Linux
+-system visible to kernel and userspace developers. It is not intended for
+-production usage as it adds significant overhead to the (hr)timer code and the
+-(hr)timer data structures.
++system visible to kernel and userspace developers. If enabled in the config
++but not used it has almost zero runtime overhead, and a relatively small
++data structure overhead. Even if collection is enabled runtime all the
++locking is per-CPU and lookup is hashed.
+
+ timer_stats should be used by kernel and userspace developers to verify that
+ their code does not make unduly use of timers. This helps to avoid unnecessary
+diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c
+index 17d7345..cbb4751 100644
+--- a/arch/i386/kernel/hpet.c
++++ b/arch/i386/kernel/hpet.c
+@@ -226,7 +226,8 @@ int __init hpet_enable(void)
+ {
+ unsigned long id;
+ uint64_t hpet_freq;
+- u64 tmp;
++ u64 tmp, start, now;
++ cycle_t t1;
+
+ if (!is_hpet_capable())
+ return 0;
+@@ -273,6 +274,27 @@ int __init hpet_enable(void)
+ /* Start the counter */
+ hpet_start_counter();
+
++ /* Verify whether hpet counter works */
++ t1 = read_hpet();
++ rdtscll(start);
++
++ /*
++ * We don't know the TSC frequency yet, but waiting for
++ * 200000 TSC cycles is safe:
++ * 4 GHz == 50us
++ * 1 GHz == 200us
++ */
++ do {
++ rep_nop();
++ rdtscll(now);
++ } while ((now - start) < 200000UL);
++
++ if (t1 == read_hpet()) {
++ printk(KERN_WARNING
++ "HPET counter not counting. HPET disabled\n");
++ goto out_nohpet;
++ }
++
+ /* Initialize and register HPET clocksource
+ *
+ * hpet period is in femto seconds per cycle
+diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
+index 3514b41..e33f51a 100644
+--- a/arch/i386/kernel/reboot.c
++++ b/arch/i386/kernel/reboot.c
+@@ -88,6 +88,14 @@ static int __init set_bios_reboot(struct dmi_system_id *d)
+ }
+
+ static struct dmi_system_id __initdata reboot_dmi_table[] = {
++ { /* Handle problems with rebooting on Dell E520's */
++ .callback = set_bios_reboot,
++ .ident = "Dell E520",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM061"),
++ },
++ },
+ { /* Handle problems with rebooting on Dell 1300's */
+ .callback = set_bios_reboot,
+ .ident = "Dell PowerEdge 1300",
+diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
+index 8fda7be..bd00876 100644
+--- a/arch/i386/oprofile/nmi_int.c
++++ b/arch/i386/oprofile/nmi_int.c
+@@ -131,7 +131,6 @@ static void nmi_save_registers(void * dummy)
+ {
+ int cpu = smp_processor_id();
+ struct op_msrs * msrs = &cpu_msrs[cpu];
+- model->fill_in_addresses(msrs);
+ nmi_cpu_save_registers(msrs);
+ }
+
+@@ -155,7 +154,7 @@ static int allocate_msrs(void)
+ size_t counters_size = sizeof(struct op_msr) * model->num_counters;
+
+ int i;
+- for_each_online_cpu(i) {
++ for_each_possible_cpu(i) {
+ cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL);
+ if (!cpu_msrs[i].counters) {
+ success = 0;
+@@ -195,6 +194,7 @@ static struct notifier_block profile_exceptions_nb = {
+ static int nmi_setup(void)
+ {
+ int err=0;
++ int cpu;
+
+ if (!allocate_msrs())
+ return -ENOMEM;
+@@ -207,6 +207,19 @@ static int nmi_setup(void)
+ /* We need to serialize save and setup for HT because the subset
+ * of msrs are distinct for save and setup operations
+ */
++
++ /* Assume saved/restored counters are the same on all CPUs */
++ model->fill_in_addresses(&cpu_msrs[0]);
++ for_each_possible_cpu (cpu) {
++ if (cpu != 0) {
++ memcpy(cpu_msrs[cpu].counters, cpu_msrs[0].counters,
++ sizeof(struct op_msr) * model->num_counters);
++
++ memcpy(cpu_msrs[cpu].controls, cpu_msrs[0].controls,
++ sizeof(struct op_msr) * model->num_controls);
++ }
++
++ }
+ on_each_cpu(nmi_save_registers, NULL, 0, 1);
+ on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
+ nmi_enabled = 1;
+diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
+index baea10a..06459ae 100644
+--- a/arch/sparc64/kernel/head.S
++++ b/arch/sparc64/kernel/head.S
+@@ -653,33 +653,54 @@ setup_tba:
+ restore
+ sparc64_boot_end:
+
+-#include "ktlb.S"
+-#include "tsb.S"
+ #include "etrap.S"
+ #include "rtrap.S"
+ #include "winfixup.S"
+ #include "entry.S"
+ #include "sun4v_tlb_miss.S"
+ #include "sun4v_ivec.S"
++#include "ktlb.S"
++#include "tsb.S"
+
+ /*
+ * The following skip makes sure the trap table in ttable.S is aligned
+ * on a 32K boundary as required by the v9 specs for TBA register.
+ *
+ * We align to a 32K boundary, then we have the 32K kernel TSB,
+- * then the 32K aligned trap table.
++ * the 64K kernel 4MB TSB, and then the 32K aligned trap table.
+ */
+ 1:
+ .skip 0x4000 + _start - 1b
+
++! 0x0000000000408000
++
+ .globl swapper_tsb
+ swapper_tsb:
+ .skip (32 * 1024)
+
+-! 0x0000000000408000
++ .globl swapper_4m_tsb
++swapper_4m_tsb:
++ .skip (64 * 1024)
++
++! 0x0000000000420000
+
++ /* Some care needs to be exercised if you try to move the
++ * location of the trap table relative to other things. For
++ * one thing there are br* instructions in some of the
++ * trap table entires which branch back to code in ktlb.S
++ * Those instructions can only handle a signed 16-bit
++ * displacement.
++ *
++ * There is a binutils bug (bugzilla #4558) which causes
++ * the relocation overflow checks for such instructions to
++ * not be done correctly. So bintuils will not notice the
++ * error and will instead write junk into the relocation and
++ * you'll have an unbootable kernel.
++ */
+ #include "ttable.S"
+
++! 0x0000000000428000
++
+ #include "systbls.S"
+
+ .data
+diff --git a/arch/sparc64/kernel/itlb_miss.S b/arch/sparc64/kernel/itlb_miss.S
+index ad46e20..5a8377b 100644
+--- a/arch/sparc64/kernel/itlb_miss.S
++++ b/arch/sparc64/kernel/itlb_miss.S
+@@ -11,12 +11,12 @@
+ /* ITLB ** ICACHE line 2: TSB compare and TLB load */
+ bne,pn %xcc, tsb_miss_itlb ! Miss
+ mov FAULT_CODE_ITLB, %g3
+- andcc %g5, _PAGE_EXEC_4U, %g0 ! Executable?
++ sethi %hi(_PAGE_EXEC_4U), %g4
++ andcc %g5, %g4, %g0 ! Executable?
+ be,pn %xcc, tsb_do_fault
+ nop ! Delay slot, fill me
+ stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load TLB
+ retry ! Trap done
+- nop
+
+ /* ITLB ** ICACHE line 3: */
+ nop
+diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
+index ec22cd6..f6fd073 100644
+--- a/arch/sparc64/kernel/pci_sun4v.c
++++ b/arch/sparc64/kernel/pci_sun4v.c
+@@ -12,6 +12,7 @@
+ #include <linux/percpu.h>
+ #include <linux/irq.h>
+ #include <linux/msi.h>
++#include <linux/log2.h>
+
+ #include <asm/pbm.h>
+ #include <asm/iommu.h>
+@@ -996,9 +997,8 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
+ {
+ struct pci_iommu *iommu = pbm->iommu;
+ struct property *prop;
+- unsigned long num_tsb_entries, sz;
++ unsigned long num_tsb_entries, sz, tsbsize;
+ u32 vdma[2], dma_mask, dma_offset;
+- int tsbsize;
+
+ prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
+ if (prop) {
+@@ -1012,31 +1012,15 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
+ vdma[1] = 0x80000000;
+ }
+
+- dma_mask = vdma[0];
+- switch (vdma[1]) {
+- case 0x20000000:
+- dma_mask |= 0x1fffffff;
+- tsbsize = 64;
+- break;
+-
+- case 0x40000000:
+- dma_mask |= 0x3fffffff;
+- tsbsize = 128;
+- break;
+-
+- case 0x80000000:
+- dma_mask |= 0x7fffffff;
+- tsbsize = 256;
+- break;
+-
+- default:
+- prom_printf("PCI-SUN4V: strange virtual-dma size.\n");
+- prom_halt();
++ if ((vdma[0] | vdma[1]) & ~IO_PAGE_MASK) {
++ prom_printf("PCI-SUN4V: strange virtual-dma[%08x:%08x].\n",
++ vdma[0], vdma[1]);
++ prom_halt();
+ };
+
+- tsbsize *= (8 * 1024);
+-
+- num_tsb_entries = tsbsize / sizeof(iopte_t);
++ dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL);
++ num_tsb_entries = vdma[1] / IO_PAGE_SIZE;
++ tsbsize = num_tsb_entries * sizeof(iopte_t);
+
+ dma_offset = vdma[0];
+
+@@ -1047,7 +1031,7 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
+ iommu->dma_addr_mask = dma_mask;
+
+ /* Allocate and initialize the free area map. */
+- sz = num_tsb_entries / 8;
++ sz = (num_tsb_entries + 7) / 8;
+ sz = (sz + 7UL) & ~7UL;
+ iommu->arena.map = kzalloc(sz, GFP_KERNEL);
+ if (!iommu->arena.map) {
+diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
+index f146071..c034d12 100644
+--- a/arch/sparc64/mm/init.c
++++ b/arch/sparc64/mm/init.c
+@@ -60,8 +60,11 @@ unsigned long kern_linear_pte_xor[2] __read_mostly;
+ unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
+
+ #ifndef CONFIG_DEBUG_PAGEALLOC
+-/* A special kernel TSB for 4MB and 256MB linear mappings. */
+-struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
++/* A special kernel TSB for 4MB and 256MB linear mappings.
++ * Space is allocated for this right after the trap table
++ * in arch/sparc64/kernel/head.S
++ */
++extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
+ #endif
+
+ #define MAX_BANKS 32
+diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
+index 5178eba..c2502fe 100644
+--- a/arch/um/os-Linux/start_up.c
++++ b/arch/um/os-Linux/start_up.c
+@@ -144,9 +144,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
+ int exit_with = WEXITSTATUS(status);
+ if (exit_with == 2)
+ non_fatal("check_ptrace : child exited with status 2. "
+- "Serious trouble happening! Try updating "
+- "your host skas patch!\nDisabling SYSEMU "
+- "support.");
++ "\nDisabling SYSEMU support.\n");
+ non_fatal("check_ptrace : child exited with exitcode %d, while "
+ "expecting %d; status 0x%x\n", exit_with,
+ exitcode, status);
+@@ -209,6 +207,7 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
+ static void __init check_sysemu(void)
+ {
+ void *stack;
++ unsigned long regs[MAX_REG_NR];
+ int pid, n, status, count=0;
+
+ non_fatal("Checking syscall emulation patch for ptrace...");
+@@ -225,11 +224,20 @@ static void __init check_sysemu(void)
+ fatal("check_sysemu : expected SIGTRAP, got status = %d",
+ status);
+
+- n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
+- os_getpid());
+- if(n < 0)
+- fatal_perror("check_sysemu : failed to modify system call "
+- "return");
++ if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
++ fatal_perror("check_sysemu : PTRACE_GETREGS failed");
++ if(PT_SYSCALL_NR(regs) != __NR_getpid){
++ non_fatal("check_sysemu got system call number %d, "
++ "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
++ goto fail;
++ }
++
++ n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
++ if(n < 0){
++ non_fatal("check_sysemu : failed to modify system call "
++ "return");
++ goto fail;
++ }
+
+ if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+ goto fail_stopped;
+diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
+index ec31534..6fd126a 100644
+--- a/arch/x86_64/mm/init.c
++++ b/arch/x86_64/mm/init.c
+@@ -776,3 +776,9 @@ int in_gate_area_no_task(unsigned long addr)
+ {
+ return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
+ }
++
++void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
++{
++ return __alloc_bootmem_core(pgdat->bdata, size,
++ SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0);
++}
+diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
+index 8fcd6a1..a2efae8 100644
+--- a/drivers/acpi/numa.c
++++ b/drivers/acpi/numa.c
+@@ -40,19 +40,19 @@ static nodemask_t nodes_found_map = NODE_MASK_NONE;
+ #define NID_INVAL -1
+
+ /* maps to convert between proximity domain and logical node ID */
+-int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
++static int pxm_to_node_map[MAX_PXM_DOMAINS]
+ = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL };
+-int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
++static int node_to_pxm_map[MAX_NUMNODES]
+ = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
+
+-int __cpuinit pxm_to_node(int pxm)
++int pxm_to_node(int pxm)
+ {
+ if (pxm < 0)
+ return NID_INVAL;
+ return pxm_to_node_map[pxm];
+ }
+
+-int __cpuinit node_to_pxm(int node)
++int node_to_pxm(int node)
+ {
+ if (node < 0)
+ return PXM_INVAL;
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index fd27227..efd87d3 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -170,6 +170,7 @@ enum {
+ AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
+ AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
+ AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
++ AHCI_FLAG_32BIT_ONLY = (1 << 28), /* force 32bit */
+ };
+
+ struct ahci_cmd_hdr {
+@@ -370,7 +371,8 @@ static const struct ata_port_info ahci_port_info[] = {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_SKIP_D2H_BSY |
+- AHCI_FLAG_IGN_SERR_INTERNAL,
++ AHCI_FLAG_IGN_SERR_INTERNAL |
++ AHCI_FLAG_32BIT_ONLY,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &ahci_ops,
+@@ -1579,6 +1581,12 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
+ probe_ent->n_ports = cap_n_ports;
+
+ using_dac = hpriv->cap & HOST_CAP_64;
++ if (using_dac && (probe_ent->port_flags & AHCI_FLAG_32BIT_ONLY)) {
++ dev_printk(KERN_INFO, &pdev->dev,
++ "controller can't do 64bit DMA, forcing 32bit\n");
++ using_dac = 0;
++ }
++
+ if (using_dac &&
+ !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
+index 65a725c..e0da175 100644
+--- a/drivers/block/cciss.c
++++ b/drivers/block/cciss.c
+@@ -3405,13 +3405,39 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
+ return -1;
+ }
+
+-static void cciss_remove_one(struct pci_dev *pdev)
++static void cciss_shutdown(struct pci_dev *pdev)
+ {
+ ctlr_info_t *tmp_ptr;
+- int i, j;
++ int i;
+ char flush_buf[4];
+ int return_code;
+
++ tmp_ptr = pci_get_drvdata(pdev);
++ if (tmp_ptr == NULL)
++ return;
++ i = tmp_ptr->ctlr;
++ if (hba[i] == NULL)
++ return;
++
++ /* Turn board interrupts off and send the flush cache command */
++ /* sendcmd will turn off interrupt, and send the flush...
++ * To write all data in the battery backed cache to disks */
++ memset(flush_buf, 0, 4);
++ return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL,
++ TYPE_CMD);
++ if (return_code == IO_OK) {
++ printk(KERN_INFO "Completed flushing cache on controller %d\n", i);
++ } else {
++ printk(KERN_WARNING "Error flushing cache on controller %d\n", i);
++ }
++ free_irq(hba[i]->intr[2], hba[i]);
++}
++
++static void __devexit cciss_remove_one(struct pci_dev *pdev)
++{
++ ctlr_info_t *tmp_ptr;
++ int i, j;
++
+ if (pci_get_drvdata(pdev) == NULL) {
+ printk(KERN_ERR "cciss: Unable to remove device \n");
+ return;
+@@ -3442,18 +3468,7 @@ static void cciss_remove_one(struct pci_dev *pdev)
+
+ cciss_unregister_scsi(i); /* unhook from SCSI subsystem */
+
+- /* Turn board interrupts off and send the flush cache command */
+- /* sendcmd will turn off interrupt, and send the flush...
+- * To write all data in the battery backed cache to disks */
+- memset(flush_buf, 0, 4);
+- return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL,
+- TYPE_CMD);
+- if (return_code == IO_OK) {
+- printk(KERN_INFO "Completed flushing cache on controller %d\n", i);
+- } else {
+- printk(KERN_WARNING "Error flushing cache on controller %d\n", i);
+- }
+- free_irq(hba[i]->intr[2], hba[i]);
++ cciss_shutdown(pdev);
+
+ #ifdef CONFIG_PCI_MSI
+ if (hba[i]->msix_vector)
+@@ -3486,7 +3501,7 @@ static struct pci_driver cciss_pci_driver = {
+ .probe = cciss_init_one,
+ .remove = __devexit_p(cciss_remove_one),
+ .id_table = cciss_pci_device_id, /* id_table */
+- .shutdown = cciss_remove_one,
++ .shutdown = cciss_shutdown,
+ };
+
+ /*
+diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
+index 16dc5d1..ab39503 100644
+--- a/drivers/char/cyclades.c
++++ b/drivers/char/cyclades.c
+@@ -1103,6 +1103,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
+
+ if (data & info->ignore_status_mask) {
+ info->icount.rx++;
++ spin_unlock(&cinfo->card_lock);
+ return;
+ }
+ if (tty_buffer_request_room(tty, 1)) {
+diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
+index 6ac3ca4..5a6c649 100644
+--- a/drivers/char/n_tty.c
++++ b/drivers/char/n_tty.c
+@@ -1191,6 +1191,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
+ is_current_pgrp_orphaned())
+ return -EIO;
+ kill_pgrp(task_pgrp(current), SIGTTIN, 1);
++ set_thread_flag(TIF_SIGPENDING);
+ return -ERESTARTSYS;
+ }
+ }
+diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+index 7a32df5..2000120 100644
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -1121,7 +1121,8 @@ int tty_check_change(struct tty_struct * tty)
+ return 0;
+ if (is_current_pgrp_orphaned())
+ return -EIO;
+- (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
++ kill_pgrp(task_pgrp(current), SIGTTOU, 1);
++ set_thread_flag(TIF_SIGPENDING);
+ return -ERESTARTSYS;
+ }
+
+diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
+index ab6fa27..cf9d344 100644
+--- a/drivers/ide/pci/hpt366.c
++++ b/drivers/ide/pci/hpt366.c
+@@ -1,5 +1,5 @@
+ /*
+- * linux/drivers/ide/pci/hpt366.c Version 1.02 Apr 18, 2007
++ * linux/drivers/ide/pci/hpt366.c Version 1.03 May 4, 2007
+ *
+ * Copyright (C) 1999-2003 Andre Hedrick <andre at linux-ide.org>
+ * Portions Copyright (C) 2001 Sun Microsystems, Inc.
+@@ -1527,7 +1527,12 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
+ if (rev > 2)
+ goto init_single;
+
++ /*
++ * HPT36x chips are single channel and
++ * do not seem to have the channel enable bit...
++ */
+ d->channels = 1;
++ d->enablebits[0].reg = 0;
+
+ if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
+ u8 pin1 = 0, pin2 = 0;
+diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
+index 03e44b3..6c81951 100644
+--- a/drivers/ieee1394/eth1394.c
++++ b/drivers/ieee1394/eth1394.c
+@@ -584,10 +584,9 @@ static void ether1394_add_host (struct hpsb_host *host)
+ }
+
+ SET_MODULE_OWNER(dev);
+-#if 0
+- /* FIXME - Is this the correct parent device anyway? */
+- SET_NETDEV_DEV(dev, &host->device);
+-#endif
++
++ /* This used to be &host->device in Linux 2.6.20 and before. */
++ SET_NETDEV_DEV(dev, host->device.parent);
+
+ priv = netdev_priv(dev);
+
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
+index db9cca3..23411ab 100644
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -526,6 +526,33 @@ static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
++/*
++ * i8042_toggle_aux - enables or disables AUX port on i8042 via command and
++ * verifies success by readinng CTR. Used when testing for presence of AUX
++ * port.
++ */
++static int __devinit i8042_toggle_aux(int on)
++{
++ unsigned char param;
++ int i;
++
++ if (i8042_command(¶m,
++ on ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE))
++ return -1;
++
++ /* some chips need some time to set the I8042_CTR_AUXDIS bit */
++ for (i = 0; i < 100; i++) {
++ udelay(50);
++
++ if (i8042_command(¶m, I8042_CMD_CTL_RCTR))
++ return -1;
++
++ if (!(param & I8042_CTR_AUXDIS) == on)
++ return 0;
++ }
++
++ return -1;
++}
+
+ /*
+ * i8042_check_aux() applies as much paranoia as it can at detecting
+@@ -580,16 +607,12 @@ static int __devinit i8042_check_aux(void)
+ * Bit assignment test - filters out PS/2 i8042's in AT mode
+ */
+
+- if (i8042_command(¶m, I8042_CMD_AUX_DISABLE))
+- return -1;
+- if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
++ if (i8042_toggle_aux(0)) {
+ printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
+ printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");
+ }
+
+- if (i8042_command(¶m, I8042_CMD_AUX_ENABLE))
+- return -1;
+- if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
++ if (i8042_toggle_aux(1))
+ return -1;
+
+ /*
+diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
+index e61e0ef..fd563a9 100644
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -255,19 +255,25 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
+
+ }
+
+-static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
++static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
+ {
+ mdk_rdev_t *rdev;
+ struct list_head *tmp;
++ mddev_t *mddev = bitmap->mddev;
+
+ ITERATE_RDEV(mddev, rdev, tmp)
+ if (test_bit(In_sync, &rdev->flags)
+- && !test_bit(Faulty, &rdev->flags))
++ && !test_bit(Faulty, &rdev->flags)) {
++ int size = PAGE_SIZE;
++ if (page->index == bitmap->file_pages-1)
++ size = roundup(bitmap->last_page_size,
++ bdev_hardsect_size(rdev->bdev));
+ md_super_write(mddev, rdev,
+- (rdev->sb_offset<<1) + offset
++ (rdev->sb_offset<<1) + bitmap->offset
+ + page->index * (PAGE_SIZE/512),
+- PAGE_SIZE,
++ size,
+ page);
++ }
+
+ if (wait)
+ md_super_wait(mddev);
+@@ -282,7 +288,7 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
+ struct buffer_head *bh;
+
+ if (bitmap->file == NULL)
+- return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
++ return write_sb_page(bitmap, page, wait);
+
+ bh = page_buffers(page);
+
+@@ -923,6 +929,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
+ }
+
+ bitmap->filemap[bitmap->file_pages++] = page;
++ bitmap->last_page_size = count;
+ }
+ paddr = kmap_atomic(page, KM_USER0);
+ if (bitmap->flags & BITMAP_HOSTENDIAN)
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index dfe3214..2c404f7 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -415,7 +415,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
+ raid0_conf_t *conf = mddev_to_conf(mddev);
+ struct strip_zone *zone;
+ mdk_rdev_t *tmp_dev;
+- unsigned long chunk;
++ sector_t chunk;
+ sector_t block, rsect;
+ const int rw = bio_data_dir(bio);
+
+@@ -470,7 +470,6 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
+
+ sector_div(x, zone->nb_dev);
+ chunk = x;
+- BUG_ON(x != (sector_t)chunk);
+
+ x = block >> chunksize_bits;
+ tmp_dev = zone->dev[sector_div(x, zone->nb_dev)];
+diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
+index 464feaf..622a329 100644
+--- a/drivers/media/dvb/ttpci/budget-ci.c
++++ b/drivers/media/dvb/ttpci/budget-ci.c
+@@ -926,7 +926,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc
+ band = 1;
+ } else if (tuner_frequency < 200000000) {
+ cp = 6;
+- band = 2;
++ band = 1;
+ } else if (tuner_frequency < 290000000) {
+ cp = 3;
+ band = 2;
+diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
+index b28a915..de907d9 100644
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -1153,13 +1153,16 @@ e1000_probe(struct pci_dev *pdev,
+ !e1000_check_mng_mode(&adapter->hw))
+ e1000_get_hw_control(adapter);
+
+- strcpy(netdev->name, "eth%d");
+- if ((err = register_netdev(netdev)))
+- goto err_register;
+-
+ /* tell the stack to leave us alone until e1000_open() is called */
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
++#ifdef CONFIG_E1000_NAPI
++ netif_poll_disable(netdev);
++#endif
++
++ strcpy(netdev->name, "eth%d");
++ if ((err = register_netdev(netdev)))
++ goto err_register;
+
+ DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
+
+diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
+index 3d20115..2de13cf 100644
+--- a/drivers/net/tg3.c
++++ b/drivers/net/tg3.c
+@@ -64,8 +64,8 @@
+
+ #define DRV_MODULE_NAME "tg3"
+ #define PFX DRV_MODULE_NAME ": "
+-#define DRV_MODULE_VERSION "3.75.1"
+-#define DRV_MODULE_RELDATE "May 7, 2007"
++#define DRV_MODULE_VERSION "3.75.2"
++#define DRV_MODULE_RELDATE "June 5, 2007"
+
+ #define TG3_DEF_MAC_MODE 0
+ #define TG3_DEF_RX_MODE 0
+@@ -10942,6 +10942,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
+ * upon subsystem IDs.
+ */
+ if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
+ !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+ tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT |
+ TG3_FLAG_USE_LINKCHG_REG);
+diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
+index 87ee3ee..e0e936a 100644
+--- a/drivers/net/wireless/zd1211rw/zd_chip.c
++++ b/drivers/net/wireless/zd1211rw/zd_chip.c
+@@ -67,11 +67,12 @@ static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
+ i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
+ i += scnprintf(buffer+i, size-i, " ");
+ i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
+- i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c", chip->pa_type,
++ i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
+ chip->patch_cck_gain ? 'g' : '-',
+ chip->patch_cr157 ? '7' : '-',
+ chip->patch_6m_band_edge ? '6' : '-',
+- chip->new_phy_layout ? 'N' : '-');
++ chip->new_phy_layout ? 'N' : '-',
++ chip->al2230s_bit ? 'S' : '-');
+ return i;
+ }
+
+diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
+index f50cff3..e6d604b 100644
+--- a/drivers/net/wireless/zd1211rw/zd_rf.c
++++ b/drivers/net/wireless/zd1211rw/zd_rf.c
+@@ -34,7 +34,7 @@ static const char *rfs[] = {
+ [AL2210_RF] = "AL2210_RF",
+ [MAXIM_NEW_RF] = "MAXIM_NEW_RF",
+ [UW2453_RF] = "UW2453_RF",
+- [AL2230S_RF] = "AL2230S_RF",
++ [UNKNOWN_A_RF] = "UNKNOWN_A_RF",
+ [RALINK_RF] = "RALINK_RF",
+ [INTERSIL_RF] = "INTERSIL_RF",
+ [RF2959_RF] = "RF2959_RF",
+diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
+index a57732e..ee8ac3a 100644
+--- a/drivers/net/wireless/zd1211rw/zd_rf.h
++++ b/drivers/net/wireless/zd1211rw/zd_rf.h
+@@ -26,7 +26,7 @@
+ #define AL2210_RF 0x7
+ #define MAXIM_NEW_RF 0x8
+ #define UW2453_RF 0x9
+-#define AL2230S_RF 0xa
++#define UNKNOWN_A_RF 0xa
+ #define RALINK_RF 0xb
+ #define INTERSIL_RF 0xc
+ #define RF2959_RF 0xd
+diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+index 5235a78..85a9ad2 100644
+--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
++++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+@@ -59,6 +59,18 @@ static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
+ { CR240, 0x57 }, { CR9, 0xe0 },
+ };
+
++static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
++ { CR47, 0x1e }, /* MARK_002 */
++ { CR106, 0x22 },
++ { CR107, 0x2a }, /* MARK_002 */
++ { CR109, 0x13 }, /* MARK_002 */
++ { CR118, 0xf8 }, /* MARK_002 */
++ { CR119, 0x12 }, { CR122, 0xe0 },
++ { CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */
++ { CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */
++ { CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */
++};
++
+ static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
+ {
+ int r;
+@@ -90,7 +102,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
+ int r;
+ struct zd_chip *chip = zd_rf_to_chip(rf);
+
+- static const struct zd_ioreq16 ioreqs[] = {
++ static const struct zd_ioreq16 ioreqs_init[] = {
+ { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 },
+ { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 },
+ { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a },
+@@ -117,10 +129,9 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
+ { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 },
+ { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff },
+ { CR253, 0xff },
++ };
+
+- /* These following happen separately in the vendor driver */
+- { },
+-
++ static const struct zd_ioreq16 ioreqs_pll[] = {
+ /* shdnb(PLL_ON)=0 */
+ { CR251, 0x2f },
+ /* shdnb(PLL_ON)=1 */
+@@ -128,7 +139,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
+ { CR138, 0x28 }, { CR203, 0x06 },
+ };
+
+- static const u32 rv[] = {
++ static const u32 rv1[] = {
+ /* Channel 1 */
+ 0x03f790,
+ 0x033331,
+@@ -137,6 +148,9 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
+ 0x0b3331,
+ 0x03b812,
+ 0x00fff3,
++ };
++
++ static const u32 rv2[] = {
+ 0x000da4,
+ 0x0f4dc5, /* fix freq shift, 0x04edc5 */
+ 0x0805b6,
+@@ -148,8 +162,9 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
+ 0x0bdffc,
+ 0x00000d,
+ 0x00500f,
++ };
+
+- /* These writes happen separately in the vendor driver */
++ static const u32 rv3[] = {
+ 0x00d00f,
+ 0x004c0f,
+ 0x00540f,
+@@ -157,11 +172,38 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
+ 0x00500f,
+ };
+
+- r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
++ r = zd_iowrite16a_locked(chip, ioreqs_init, ARRAY_SIZE(ioreqs_init));
+ if (r)
+ return r;
+
+- r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
++ if (chip->al2230s_bit) {
++ r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
++ ARRAY_SIZE(ioreqs_init_al2230s));
++ if (r)
++ return r;
++ }
++
++ r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS);
++ if (r)
++ return r;
++
++ /* improve band edge for AL2230S */
++ if (chip->al2230s_bit)
++ r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS);
++ else
++ r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS);
++ if (r)
++ return r;
++
++ r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS);
++ if (r)
++ return r;
++
++ r = zd_iowrite16a_locked(chip, ioreqs_pll, ARRAY_SIZE(ioreqs_pll));
++ if (r)
++ return r;
++
++ r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS);
+ if (r)
+ return r;
+
+@@ -227,7 +269,9 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
+ 0x481dc0,
+ 0xcfff00,
+ 0x25a000,
++ };
+
++ static const u32 rv2[] = {
+ /* To improve AL2230 yield, improve phase noise, 4713 */
+ 0x25a000,
+ 0xa3b2f0,
+@@ -250,7 +294,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
+ { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
+ };
+
+- static const u32 rv2[] = {
++ static const u32 rv3[] = {
+ /* To improve AL2230 yield, 4713 */
+ 0xf01b00,
+ 0xf01e00,
+@@ -269,18 +313,37 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
+ r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1));
+ if (r)
+ return r;
++
++ if (chip->al2230s_bit) {
++ r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
++ ARRAY_SIZE(ioreqs_init_al2230s));
++ if (r)
++ return r;
++ }
++
+ r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3);
+ if (r)
+ return r;
+ r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1));
+ if (r)
+ return r;
+- r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
++
++ if (chip->al2230s_bit)
++ r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS);
++ else
++ r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS);
+ if (r)
+ return r;
++
+ r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2));
+ if (r)
+ return r;
++ r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
++ if (r)
++ return r;
++ r = zd_rfwritev_cr_locked(chip, rv3, ARRAY_SIZE(rv3));
++ if (r)
++ return r;
+ r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3));
+ if (r)
+ return r;
+@@ -358,12 +421,6 @@ int zd_rf_init_al2230(struct zd_rf *rf)
+ {
+ struct zd_chip *chip = zd_rf_to_chip(rf);
+
+- if (chip->al2230s_bit) {
+- dev_err(zd_chip_dev(chip), "AL2230S devices are not yet "
+- "supported by this driver.\n");
+- return -ENODEV;
+- }
+-
+ rf->switch_radio_off = al2230_switch_radio_off;
+ if (chip->is_zd1211b) {
+ rf->init_hw = zd1211b_al2230_init_hw;
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 5af9125..e2d81af 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -1751,6 +1751,7 @@ static void __init quirk_disable_all_msi(struct pci_dev *dev)
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
+
+ /* Disable MSI on chipsets that are known to not support it */
+ static void __devinit quirk_disable_msi(struct pci_dev *dev)
+diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
+index 39ecd0d..1eca9cd 100644
+--- a/drivers/scsi/aacraid/aacraid.h
++++ b/drivers/scsi/aacraid/aacraid.h
+@@ -1840,6 +1840,7 @@ struct aac_driver_ident* aac_get_driver_ident(int devtype);
+ int aac_get_adapter_info(struct aac_dev* dev);
+ int aac_send_shutdown(struct aac_dev *dev);
+ int aac_probe_container(struct aac_dev *dev, int cid);
++int aac_rx_deliver_producer(struct fib * fib);
+ extern int numacb;
+ extern int acbsize;
+ extern char aac_driver_version[];
+diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
+index d242e26..4431a5d 100644
+--- a/drivers/scsi/aacraid/rx.c
++++ b/drivers/scsi/aacraid/rx.c
+@@ -378,7 +378,7 @@ static int aac_rx_check_health(struct aac_dev *dev)
+ *
+ * Will send a fib, returning 0 if successful.
+ */
+-static int aac_rx_deliver_producer(struct fib * fib)
++int aac_rx_deliver_producer(struct fib * fib)
+ {
+ struct aac_dev *dev = fib->dev;
+ struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
+diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
+index 6f1a178..06744f0 100644
+--- a/drivers/scsi/aacraid/sa.c
++++ b/drivers/scsi/aacraid/sa.c
+@@ -5,7 +5,7 @@
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+- * Copyright (c) 2000 Adaptec, Inc. (aacraid at adaptec.com)
++ * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid at adaptec.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -368,6 +368,7 @@ int aac_sa_init(struct aac_dev *dev)
+ dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
+ dev->a_ops.adapter_check_health = aac_sa_check_health;
+ dev->a_ops.adapter_intr = aac_sa_intr;
++ dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
+ dev->a_ops.adapter_ioremap = aac_sa_ioremap;
+
+ /*
+diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
+index e35d9ab..b45ba53 100644
+--- a/drivers/serial/suncore.c
++++ b/drivers/serial/suncore.c
+@@ -30,9 +30,9 @@ void
+ sunserial_console_termios(struct console *con)
+ {
+ char mode[16], buf[16], *s;
+- char *mode_prop = "ttyX-mode";
+- char *cd_prop = "ttyX-ignore-cd";
+- char *dtr_prop = "ttyX-rts-dtr-off";
++ char mode_prop[] = "ttyX-mode";
++ char cd_prop[] = "ttyX-ignore-cd";
++ char dtr_prop[] = "ttyX-rts-dtr-off";
+ char *ssp_console_modes_prop = "ssp-console-modes";
+ int baud, bits, stop, cflag;
+ char parity;
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+index 217a3d6..2f17468 100644
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -221,15 +221,10 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
+
+ if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_INT) {
+- int interval;
+-
+- if (usb_dev->speed == USB_SPEED_HIGH)
+- interval = 1 << min(15, ep->desc.bInterval - 1);
+- else
+- interval = ep->desc.bInterval;
+ pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
+ usb_fill_int_urb(urb, usb_dev, pipe, data, len,
+- usb_api_blocking_completion, NULL, interval);
++ usb_api_blocking_completion, NULL,
++ ep->desc.bInterval);
+ } else
+ usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
+ usb_api_blocking_completion, NULL);
+diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
+index 395cced..fec4d25 100644
+--- a/drivers/video/neofb.c
++++ b/drivers/video/neofb.c
+@@ -1285,34 +1285,36 @@ static int neofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ if (regno >= fb->cmap.len || regno > 255)
+ return -EINVAL;
+
+- switch (fb->var.bits_per_pixel) {
+- case 8:
++ if (fb->var.bits_per_pixel <= 8) {
+ outb(regno, 0x3c8);
+
+ outb(red >> 10, 0x3c9);
+ outb(green >> 10, 0x3c9);
+ outb(blue >> 10, 0x3c9);
+- break;
+- case 16:
+- ((u32 *) fb->pseudo_palette)[regno] =
++ } else if (regno < 16) {
++ switch (fb->var.bits_per_pixel) {
++ case 16:
++ ((u32 *) fb->pseudo_palette)[regno] =
+ ((red & 0xf800)) | ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11);
+- break;
+- case 24:
+- ((u32 *) fb->pseudo_palette)[regno] =
++ break;
++ case 24:
++ ((u32 *) fb->pseudo_palette)[regno] =
+ ((red & 0xff00) << 8) | ((green & 0xff00)) |
+ ((blue & 0xff00) >> 8);
+- break;
++ break;
+ #ifdef NO_32BIT_SUPPORT_YET
+- case 32:
+- ((u32 *) fb->pseudo_palette)[regno] =
++ case 32:
++ ((u32 *) fb->pseudo_palette)[regno] =
+ ((transp & 0xff00) << 16) | ((red & 0xff00) << 8) |
+ ((green & 0xff00)) | ((blue & 0xff00) >> 8);
+- break;
++ break;
+ #endif
+- default:
+- return 1;
++ default:
++ return 1;
++ }
+ }
++
+ return 0;
+ }
+
+diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
+index 8b1c5d8..57c3b1c 100644
+--- a/fs/compat_ioctl.c
++++ b/fs/compat_ioctl.c
+@@ -1178,6 +1178,7 @@ static int vt_check(struct file *file)
+ {
+ struct tty_struct *tty;
+ struct inode *inode = file->f_path.dentry->d_inode;
++ struct vc_data *vc;
+
+ if (file->f_op->ioctl != tty_ioctl)
+ return -EINVAL;
+@@ -1188,12 +1189,16 @@ static int vt_check(struct file *file)
+
+ if (tty->driver->ioctl != vt_ioctl)
+ return -EINVAL;
+-
++
++ vc = (struct vc_data *)tty->driver_data;
++ if (!vc_cons_allocated(vc->vc_num)) /* impossible? */
++ return -ENOIOCTLCMD;
++
+ /*
+ * To have permissions to do most of the vt ioctls, we either have
+- * to be the owner of the tty, or super-user.
++ * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
+ */
+- if (current->signal->tty == tty || capable(CAP_SYS_ADMIN))
++ if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+ return 1;
+ return 0;
+ }
+@@ -1294,16 +1299,28 @@ static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
+ struct unimapdesc32 tmp;
+ struct unimapdesc32 __user *user_ud = compat_ptr(arg);
+ int perm = vt_check(file);
+-
+- if (perm < 0) return perm;
++ struct vc_data *vc;
++
++ if (perm < 0)
++ return perm;
+ if (copy_from_user(&tmp, user_ud, sizeof tmp))
+ return -EFAULT;
++ if (tmp.entries)
++ if (!access_ok(VERIFY_WRITE, compat_ptr(tmp.entries),
++ tmp.entry_ct*sizeof(struct unipair)))
++ return -EFAULT;
++ vc = ((struct tty_struct *)file->private_data)->driver_data;
+ switch (cmd) {
+ case PIO_UNIMAP:
+- if (!perm) return -EPERM;
+- return con_set_unimap(vc_cons[fg_console].d, tmp.entry_ct, compat_ptr(tmp.entries));
++ if (!perm)
++ return -EPERM;
++ return con_set_unimap(vc, tmp.entry_ct,
++ compat_ptr(tmp.entries));
+ case GIO_UNIMAP:
+- return con_get_unimap(vc_cons[fg_console].d, tmp.entry_ct, &(user_ud->entry_ct), compat_ptr(tmp.entries));
++ if (!perm && fg_console != vc->vc_num)
++ return -EPERM;
++ return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
++ compat_ptr(tmp.entries));
+ }
+ return 0;
+ }
+diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
+index 8890eba..bd5a772 100644
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -485,7 +485,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
+ static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
+ struct nameidata *nd)
+ {
+- if (nd && (nd->flags & LOOKUP_CREATE)) {
++ if (nd && (nd->flags & LOOKUP_OPEN)) {
+ int err = fuse_create_open(dir, entry, mode, nd);
+ if (err != -ENOSYS)
+ return err;
+diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
+index f8bf8da..461460d 100644
+--- a/fs/ntfs/inode.c
++++ b/fs/ntfs/inode.c
+@@ -141,7 +141,7 @@ static int ntfs_init_locked_inode(struct inode *vi, ntfs_attr *na)
+ if (!ni->name)
+ return -ENOMEM;
+ memcpy(ni->name, na->name, i);
+- ni->name[i] = 0;
++ ni->name[na->name_len] = 0;
+ }
+ return 0;
+ }
+diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h
+index 1049f2a..13a7c5b 100644
+--- a/include/acpi/acpi_numa.h
++++ b/include/acpi/acpi_numa.h
+@@ -11,11 +11,8 @@
+ #define MAX_PXM_DOMAINS (256) /* Old pxm spec is defined 8 bit */
+ #endif
+
+-extern int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS];
+-extern int __cpuinitdata node_to_pxm_map[MAX_NUMNODES];
+-
+-extern int __cpuinit pxm_to_node(int);
+-extern int __cpuinit node_to_pxm(int);
++extern int pxm_to_node(int);
++extern int node_to_pxm(int);
+ extern int __cpuinit acpi_map_pxm_to_node(int);
+ extern void __cpuinit acpi_unmap_pxm_to_node(int);
+
+diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h
+index ab55ffc..76e4299 100644
+--- a/include/asm-sparc64/tsb.h
++++ b/include/asm-sparc64/tsb.h
+@@ -271,7 +271,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
+ #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
+ sethi %hi(swapper_4m_tsb), REG1; \
+ or REG1, %lo(swapper_4m_tsb), REG1; \
+- and TAG, (KERNEL_TSB_NENTRIES - 1), REG2; \
++ and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
+ sllx REG2, 4, REG2; \
+ add REG1, REG2, REG2; \
+ KTSB_LOAD_QUAD(REG2, REG3); \
+diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
+index 81c07cd..9543a55 100644
+--- a/include/linux/bootmem.h
++++ b/include/linux/bootmem.h
+@@ -59,6 +59,7 @@ extern void *__alloc_bootmem_core(struct bootmem_data *bdata,
+ unsigned long align,
+ unsigned long goal,
+ unsigned long limit);
++extern void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size);
+
+ #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
+ extern void reserve_bootmem(unsigned long addr, unsigned long size);
+diff --git a/include/linux/mii.h b/include/linux/mii.h
+index beddc6d..151b7e0 100644
+--- a/include/linux/mii.h
++++ b/include/linux/mii.h
+@@ -56,8 +56,8 @@
+ #define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+ #define BMSR_RESV 0x00c0 /* Unused... */
+ #define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+-#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */
+-#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */
++#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
++#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
+ #define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+ #define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+ #define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index 600308f..db2ba30 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -1287,6 +1287,7 @@
+ #define PCI_DEVICE_ID_VIA_P4M800CE 0x0314
+ #define PCI_DEVICE_ID_VIA_P4M890 0x0327
+ #define PCI_DEVICE_ID_VIA_VT3336 0x0336
++#define PCI_DEVICE_ID_VIA_VT3351 0x0351
+ #define PCI_DEVICE_ID_VIA_8371_0 0x0391
+ #define PCI_DEVICE_ID_VIA_8501_0 0x0501
+ #define PCI_DEVICE_ID_VIA_82C561 0x0561
+@@ -2259,11 +2260,11 @@
+ #define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e
+ #define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850
+ #define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910
+-#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2911
++#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2917
+ #define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912
+ #define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913
+ #define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914
+-#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2915
++#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919
+ #define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
+ #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
+ #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
+diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
+index 6db9a4c..dd5a05d 100644
+--- a/include/linux/raid/bitmap.h
++++ b/include/linux/raid/bitmap.h
+@@ -232,6 +232,7 @@ struct bitmap {
+ struct page **filemap; /* list of cache pages for the file */
+ unsigned long *filemap_attr; /* attributes associated w/ filemap pages */
+ unsigned long file_pages; /* number of pages in the file */
++ int last_page_size; /* bytes in the last page */
+
+ unsigned long flags;
+
+diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
+index 2a7b38d..1a76bda 100644
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -162,7 +162,7 @@ extern struct workqueue_struct *__create_workqueue(const char *name,
+ int singlethread,
+ int freezeable);
+ #define create_workqueue(name) __create_workqueue((name), 0, 0)
+-#define create_freezeable_workqueue(name) __create_workqueue((name), 0, 1)
++#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1)
+ #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0)
+
+ extern void destroy_workqueue(struct workqueue_struct *wq);
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index c0398f5..65f49fd 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -62,13 +62,11 @@ struct unix_skb_parms {
+ #define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
+ #define UNIXSID(skb) (&UNIXCB((skb)).secid)
+
+-#define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock)
+-#define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock)
+-#define unix_state_wlock(s) spin_lock(&unix_sk(s)->lock)
+-#define unix_state_wlock_nested(s) \
++#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock)
++#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock)
++#define unix_state_lock_nested(s) \
+ spin_lock_nested(&unix_sk(s)->lock, \
+ SINGLE_DEPTH_NESTING)
+-#define unix_state_wunlock(s) spin_unlock(&unix_sk(s)->lock)
+
+ #ifdef __KERNEL__
+ /* The AF_UNIX socket */
+diff --git a/kernel/sched.c b/kernel/sched.c
+index b9a6837..a3993b9 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -4545,9 +4545,7 @@ int __sched cond_resched_softirq(void)
+ BUG_ON(!in_softirq());
+
+ if (need_resched() && system_state == SYSTEM_RUNNING) {
+- raw_local_irq_disable();
+- _local_bh_enable();
+- raw_local_irq_enable();
++ local_bh_enable();
+ __cond_resched();
+ local_bh_disable();
+ return 1;
+diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
+index eadfce2..8001d37 100644
+--- a/kernel/time/tick-broadcast.c
++++ b/kernel/time/tick-broadcast.c
+@@ -243,11 +243,18 @@ void tick_broadcast_on_off(unsigned long reason, int *oncpu)
+ {
+ int cpu = get_cpu();
+
+- if (cpu == *oncpu)
+- tick_do_broadcast_on_off(&reason);
+- else
+- smp_call_function_single(*oncpu, tick_do_broadcast_on_off,
+- &reason, 1, 1);
++ if (!cpu_isset(*oncpu, cpu_online_map)) {
++ printk(KERN_ERR "tick-braodcast: ignoring broadcast for "
++ "offline CPU #%d\n", *oncpu);
++ } else {
++
++ if (cpu == *oncpu)
++ tick_do_broadcast_on_off(&reason);
++ else
++ smp_call_function_single(*oncpu,
++ tick_do_broadcast_on_off,
++ &reason, 1, 1);
++ }
+ put_cpu();
+ }
+
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index f4fc867..d9a864f 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -167,9 +167,15 @@ void tick_nohz_stop_sched_tick(void)
+ goto end;
+
+ cpu = smp_processor_id();
+- if (unlikely(local_softirq_pending()))
+- printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
+- local_softirq_pending());
++ if (unlikely(local_softirq_pending())) {
++ static int ratelimit;
++
++ if (ratelimit < 10) {
++ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
++ local_softirq_pending());
++ ratelimit++;
++ }
++ }
+
+ now = ktime_get();
+ /*
+diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
+index 1bc4882..73ddbeb 100644
+--- a/kernel/time/timer_stats.c
++++ b/kernel/time/timer_stats.c
+@@ -117,21 +117,6 @@ static struct entry entries[MAX_ENTRIES];
+
+ static atomic_t overflow_count;
+
+-static void reset_entries(void)
+-{
+- nr_entries = 0;
+- memset(entries, 0, sizeof(entries));
+- atomic_set(&overflow_count, 0);
+-}
+-
+-static struct entry *alloc_entry(void)
+-{
+- if (nr_entries >= MAX_ENTRIES)
+- return NULL;
+-
+- return entries + nr_entries++;
+-}
+-
+ /*
+ * The entries are in a hash-table, for fast lookup:
+ */
+@@ -149,6 +134,22 @@ static struct entry *alloc_entry(void)
+
+ static struct entry *tstat_hash_table[TSTAT_HASH_SIZE] __read_mostly;
+
++static void reset_entries(void)
++{
++ nr_entries = 0;
++ memset(entries, 0, sizeof(entries));
++ memset(tstat_hash_table, 0, sizeof(tstat_hash_table));
++ atomic_set(&overflow_count, 0);
++}
++
++static struct entry *alloc_entry(void)
++{
++ if (nr_entries >= MAX_ENTRIES)
++ return NULL;
++
++ return entries + nr_entries++;
++}
++
+ static int match_entries(struct entry *entry1, struct entry *entry2)
+ {
+ return entry1->timer == entry2->timer &&
+@@ -202,12 +203,15 @@ static struct entry *tstat_lookup(struct entry *entry, char *comm)
+ if (curr) {
+ *curr = *entry;
+ curr->count = 0;
++ curr->next = NULL;
+ memcpy(curr->comm, comm, TASK_COMM_LEN);
++
++ smp_mb(); /* Ensure that curr is initialized before insert */
++
+ if (prev)
+ prev->next = curr;
+ else
+ *head = curr;
+- curr->next = NULL;
+ }
+ out_unlock:
+ spin_unlock(&table_lock);
+@@ -232,10 +236,15 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
+ /*
+ * It doesnt matter which lock we take:
+ */
+- spinlock_t *lock = &per_cpu(lookup_lock, raw_smp_processor_id());
++ spinlock_t *lock;
+ struct entry *entry, input;
+ unsigned long flags;
+
++ if (likely(!active))
++ return;
++
++ lock = &per_cpu(lookup_lock, raw_smp_processor_id());
++
+ input.timer = timer;
+ input.start_func = startf;
+ input.expire_func = timerf;
+@@ -364,6 +373,7 @@ static ssize_t tstats_write(struct file *file, const char __user *buf,
+ if (!active) {
+ reset_entries();
+ time_start = ktime_get();
++ smp_mb();
+ active = 1;
+ }
+ break;
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 3f3e740..c93a502 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -143,7 +143,10 @@ config TIMER_STATS
+ reprogrammed. The statistics can be read from /proc/timer_stats.
+ The statistics collection is started by writing 1 to /proc/timer_stats,
+ writing 0 stops it. This feature is useful to collect information
+- about timer usage patterns in kernel and userspace.
++ about timer usage patterns in kernel and userspace. This feature
++ is lightweight if enabled in the kernel config but not activated
++ (it defaults to deactivated on bootup and will only be activated
++ if some application like powertop activates it explicitly).
+
+ config DEBUG_SLAB
+ bool "Debug slab memory allocations"
+diff --git a/mm/sparse.c b/mm/sparse.c
+index ac26eb0..faa08e2 100644
+--- a/mm/sparse.c
++++ b/mm/sparse.c
+@@ -209,6 +209,12 @@ static int sparse_init_one_section(struct mem_section *ms,
+ return 1;
+ }
+
++__attribute__((weak))
++void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
++{
++ return NULL;
++}
++
+ static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
+ {
+ struct page *map;
+@@ -219,6 +225,11 @@ static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
+ if (map)
+ return map;
+
++ map = alloc_bootmem_high_node(NODE_DATA(nid),
++ sizeof(struct page) * PAGES_PER_SECTION);
++ if (map)
++ return map;
++
+ map = alloc_bootmem_node(NODE_DATA(nid),
+ sizeof(struct page) * PAGES_PER_SECTION);
+ if (map)
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 71f5cfb..2f6e1ea 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -656,7 +656,8 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event,
+ /* Detach sockets from device */
+ read_lock(&hci_sk_list.lock);
+ sk_for_each(sk, node, &hci_sk_list.head) {
+- lock_sock(sk);
++ local_bh_disable();
++ bh_lock_sock_nested(sk);
+ if (hci_pi(sk)->hdev == hdev) {
+ hci_pi(sk)->hdev = NULL;
+ sk->sk_err = EPIPE;
+@@ -665,7 +666,8 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event,
+
+ hci_dev_put(hdev);
+ }
+- release_sock(sk);
++ bh_unlock_sock(sk);
++ local_bh_enable();
+ }
+ read_unlock(&hci_sk_list.lock);
+ }
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 4dc93cc..0caddcf 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3135,7 +3135,6 @@ void netdev_run_todo(void)
+ continue;
+ }
+
+- netdev_unregister_sysfs(dev);
+ dev->reg_state = NETREG_UNREGISTERED;
+
+ netdev_wait_allrefs(dev);
+@@ -3146,11 +3145,11 @@ void netdev_run_todo(void)
+ BUG_TRAP(!dev->ip6_ptr);
+ BUG_TRAP(!dev->dn_ptr);
+
+- /* It must be the very last action,
+- * after this 'dev' may point to freed up memory.
+- */
+ if (dev->destructor)
+ dev->destructor(dev);
++
++ /* Free network device */
++ kobject_put(&dev->dev.kobj);
+ }
+
+ out:
+@@ -3305,6 +3304,9 @@ void unregister_netdevice(struct net_device *dev)
+ /* Notifier chain MUST detach us from master device. */
+ BUG_TRAP(!dev->master);
+
++ /* Remove entries from sysfs */
++ netdev_unregister_sysfs(dev);
++
+ /* Finish processing unregister after unlock */
+ net_set_todo(dev);
+
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index 4cbb129..1fb7aec 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -451,9 +451,15 @@ static struct class net_class = {
+ #endif
+ };
+
++/* Delete sysfs entries but hold kobject reference until after all
++ * netdev references are gone.
++ */
+ void netdev_unregister_sysfs(struct net_device * net)
+ {
+- device_del(&(net->dev));
++ struct device *dev = &(net->dev);
++
++ kobject_get(&dev->kobj);
++ device_del(dev);
+ }
+
+ /* Create sysfs entries for network device. */
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 27c4f62..a36a965 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -204,7 +204,19 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
+ return -EINVAL;
+ if (copy_from_user(&tv, optval, sizeof(tv)))
+ return -EFAULT;
+-
++ if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
++ return -EDOM;
++
++ if (tv.tv_sec < 0) {
++ static int warned = 0;
++ *timeo_p = 0;
++ if (warned < 10 && net_ratelimit())
++ warned++;
++ printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
++ "tries to set negative timeout\n",
++ current->comm, current->pid);
++ return 0;
++ }
+ *timeo_p = MAX_SCHEDULE_TIMEOUT;
+ if (tv.tv_sec == 0 && tv.tv_usec == 0)
+ return 0;
+diff --git a/net/core/utils.c b/net/core/utils.c
+index 07236c1..24c30c1 100644
+--- a/net/core/utils.c
++++ b/net/core/utils.c
+@@ -137,16 +137,16 @@ int in4_pton(const char *src, int srclen,
+ while(1) {
+ int c;
+ c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
+- if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) {
++ if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK))) {
+ goto out;
+ }
+- if (c & (IN6PTON_DOT | IN6PTON_DELIM)) {
++ if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+ if (w == 0)
+ goto out;
+ *d++ = w & 0xff;
+ w = 0;
+ i++;
+- if (c & IN6PTON_DELIM) {
++ if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+ if (i != 4)
+ goto out;
+ break;
+diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
+index 9e8ef50..5fc4a05 100644
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -43,11 +43,11 @@ config IP_ADVANCED_ROUTER
+ asymmetric routing (packets from you to a host take a different path
+ than packets from that host to you) or if you operate a non-routing
+ host which has several IP addresses on different interfaces. To turn
+- rp_filter off use:
++ rp_filter on use:
+
+- echo 0 > /proc/sys/net/ipv4/conf/<device>/rp_filter
++ echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter
+ or
+- echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
++ echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
+
+ If unsure, say N here.
+
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 4b7a0d9..03d9659 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -513,9 +513,15 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
+
+ saddr = iph->daddr;
+ if (!(rt->rt_flags & RTCF_LOCAL)) {
+- if (sysctl_icmp_errors_use_inbound_ifaddr)
+- saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
+- else
++ struct net_device *dev = NULL;
++
++ if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr)
++ dev = dev_get_by_index(rt->fl.iif);
++
++ if (dev) {
++ saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
++ dev_put(dev);
++ } else
+ saddr = 0;
+ }
+
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 43fb160..fbe7714 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -31,10 +31,8 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);
+
+ /*
+ * This array holds the first and last local port number.
+- * For high-usage systems, use sysctl to change this to
+- * 32768-61000
+ */
+-int sysctl_local_port_range[2] = { 1024, 4999 };
++int sysctl_local_port_range[2] = { 32768, 61000 };
+
+ int inet_csk_bind_conflict(const struct sock *sk,
+ const struct inet_bind_bucket *tb)
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 824c6b9..5055190 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2445,13 +2445,10 @@ void __init tcp_init(void)
+ order++)
+ ;
+ if (order >= 4) {
+- sysctl_local_port_range[0] = 32768;
+- sysctl_local_port_range[1] = 61000;
+ tcp_death_row.sysctl_max_tw_buckets = 180000;
+ sysctl_tcp_max_orphans = 4096 << (order - 4);
+ sysctl_max_syn_backlog = 1024;
+ } else if (order < 3) {
+- sysctl_local_port_range[0] = 1024 * (3 - order);
+ tcp_death_row.sysctl_max_tw_buckets >>= (3 - order);
+ sysctl_tcp_max_orphans >>= (3 - order);
+ sysctl_max_syn_backlog = 128;
+diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
+index 78e80de..9fcf6d8 100644
+--- a/net/ipv4/xfrm4_input.c
++++ b/net/ipv4/xfrm4_input.c
+@@ -138,10 +138,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+ nf_reset(skb);
+
+ if (decaps) {
+- if (!(skb->dev->flags&IFF_LOOPBACK)) {
+- dst_release(skb->dst);
+- skb->dst = NULL;
+- }
++ dst_release(skb->dst);
++ skb->dst = NULL;
+ netif_rx(skb);
+ return 0;
+ } else {
+diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
+index ceb4376..5115574 100644
+--- a/net/ipv4/xfrm4_mode_tunnel.c
++++ b/net/ipv4/xfrm4_mode_tunnel.c
+@@ -84,6 +84,8 @@ static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
+ top_iph->saddr = x->props.saddr.a4;
+ top_iph->daddr = x->id.daddr.a4;
+
++ skb->protocol = htons(ETH_P_IP);
++
+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+ return 0;
+ }
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index 268f476..5983c54 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -619,14 +619,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
+
+ ins = &fn->leaf;
+
+- if (fn->fn_flags&RTN_TL_ROOT &&
+- fn->leaf == &ip6_null_entry &&
+- !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){
+- fn->leaf = rt;
+- rt->u.dst.rt6_next = NULL;
+- goto out;
+- }
+-
+ for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) {
+ /*
+ * Search for duplicates
+diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
+index 31f651f..c53c0d3 100644
+--- a/net/ipv6/xfrm6_input.c
++++ b/net/ipv6/xfrm6_input.c
+@@ -104,10 +104,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
+ nf_reset(skb);
+
+ if (decaps) {
+- if (!(skb->dev->flags&IFF_LOOPBACK)) {
+- dst_release(skb->dst);
+- skb->dst = NULL;
+- }
++ dst_release(skb->dst);
++ skb->dst = NULL;
+ netif_rx(skb);
+ return -1;
+ } else {
+diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
+index 0bc866c..8741bcd 100644
+--- a/net/ipv6/xfrm6_mode_tunnel.c
++++ b/net/ipv6/xfrm6_mode_tunnel.c
+@@ -80,6 +80,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
+ top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
+ ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+ ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
++ skb->protocol = htons(ETH_P_IPV6);
+ return 0;
+ }
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 6069716..f464c43 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -175,11 +175,11 @@ static struct sock *unix_peer_get(struct sock *s)
+ {
+ struct sock *peer;
+
+- unix_state_rlock(s);
++ unix_state_lock(s);
+ peer = unix_peer(s);
+ if (peer)
+ sock_hold(peer);
+- unix_state_runlock(s);
++ unix_state_unlock(s);
+ return peer;
+ }
+
+@@ -370,7 +370,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
+ unix_remove_socket(sk);
+
+ /* Clear state */
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ sock_orphan(sk);
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ dentry = u->dentry;
+@@ -379,7 +379,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
+ u->mnt = NULL;
+ state = sk->sk_state;
+ sk->sk_state = TCP_CLOSE;
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+
+ wake_up_interruptible_all(&u->peer_wait);
+
+@@ -387,12 +387,12 @@ static int unix_release_sock (struct sock *sk, int embrion)
+
+ if (skpair!=NULL) {
+ if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
+- unix_state_wlock(skpair);
++ unix_state_lock(skpair);
+ /* No more writes */
+ skpair->sk_shutdown = SHUTDOWN_MASK;
+ if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
+ skpair->sk_err = ECONNRESET;
+- unix_state_wunlock(skpair);
++ unix_state_unlock(skpair);
+ skpair->sk_state_change(skpair);
+ read_lock(&skpair->sk_callback_lock);
+ sk_wake_async(skpair,1,POLL_HUP);
+@@ -449,7 +449,7 @@ static int unix_listen(struct socket *sock, int backlog)
+ err = -EINVAL;
+ if (!u->addr)
+ goto out; /* No listens on an unbound socket */
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
+ goto out_unlock;
+ if (backlog > sk->sk_max_ack_backlog)
+@@ -463,7 +463,7 @@ static int unix_listen(struct socket *sock, int backlog)
+ err = 0;
+
+ out_unlock:
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ out:
+ return err;
+ }
+@@ -859,6 +859,31 @@ out_mknod_parent:
+ goto out_up;
+ }
+
++static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
++{
++ if (unlikely(sk1 == sk2) || !sk2) {
++ unix_state_lock(sk1);
++ return;
++ }
++ if (sk1 < sk2) {
++ unix_state_lock(sk1);
++ unix_state_lock_nested(sk2);
++ } else {
++ unix_state_lock(sk2);
++ unix_state_lock_nested(sk1);
++ }
++}
++
++static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
++{
++ if (unlikely(sk1 == sk2) || !sk2) {
++ unix_state_unlock(sk1);
++ return;
++ }
++ unix_state_unlock(sk1);
++ unix_state_unlock(sk2);
++}
++
+ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
+ int alen, int flags)
+ {
+@@ -878,11 +903,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
+ !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
+ goto out;
+
++restart:
+ other=unix_find_other(sunaddr, alen, sock->type, hash, &err);
+ if (!other)
+ goto out;
+
+- unix_state_wlock(sk);
++ unix_state_double_lock(sk, other);
++
++ /* Apparently VFS overslept socket death. Retry. */
++ if (sock_flag(other, SOCK_DEAD)) {
++ unix_state_double_unlock(sk, other);
++ sock_put(other);
++ goto restart;
++ }
+
+ err = -EPERM;
+ if (!unix_may_send(sk, other))
+@@ -897,7 +930,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
+ * 1003.1g breaking connected state with AF_UNSPEC
+ */
+ other = NULL;
+- unix_state_wlock(sk);
++ unix_state_double_lock(sk, other);
+ }
+
+ /*
+@@ -906,19 +939,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
+ if (unix_peer(sk)) {
+ struct sock *old_peer = unix_peer(sk);
+ unix_peer(sk)=other;
+- unix_state_wunlock(sk);
++ unix_state_double_unlock(sk, other);
+
+ if (other != old_peer)
+ unix_dgram_disconnected(sk, old_peer);
+ sock_put(old_peer);
+ } else {
+ unix_peer(sk)=other;
+- unix_state_wunlock(sk);
++ unix_state_double_unlock(sk, other);
+ }
+ return 0;
+
+ out_unlock:
+- unix_state_wunlock(sk);
++ unix_state_double_unlock(sk, other);
+ sock_put(other);
+ out:
+ return err;
+@@ -937,7 +970,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo)
+ (skb_queue_len(&other->sk_receive_queue) >
+ other->sk_max_ack_backlog);
+
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+
+ if (sched)
+ timeo = schedule_timeout(timeo);
+@@ -995,11 +1028,11 @@ restart:
+ goto out;
+
+ /* Latch state of peer */
+- unix_state_rlock(other);
++ unix_state_lock(other);
+
+ /* Apparently VFS overslept socket death. Retry. */
+ if (sock_flag(other, SOCK_DEAD)) {
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ sock_put(other);
+ goto restart;
+ }
+@@ -1049,18 +1082,18 @@ restart:
+ goto out_unlock;
+ }
+
+- unix_state_wlock_nested(sk);
++ unix_state_lock_nested(sk);
+
+ if (sk->sk_state != st) {
+- unix_state_wunlock(sk);
+- unix_state_runlock(other);
++ unix_state_unlock(sk);
++ unix_state_unlock(other);
+ sock_put(other);
+ goto restart;
+ }
+
+ err = security_unix_stream_connect(sock, other->sk_socket, newsk);
+ if (err) {
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ goto out_unlock;
+ }
+
+@@ -1097,7 +1130,7 @@ restart:
+ smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */
+ unix_peer(sk) = newsk;
+
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+
+ /* take ten and and send info to listening sock */
+ spin_lock(&other->sk_receive_queue.lock);
+@@ -1106,14 +1139,14 @@ restart:
+ * is installed to listening socket. */
+ atomic_inc(&newu->inflight);
+ spin_unlock(&other->sk_receive_queue.lock);
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ other->sk_data_ready(other, 0);
+ sock_put(other);
+ return 0;
+
+ out_unlock:
+ if (other)
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+
+ out:
+ if (skb)
+@@ -1179,10 +1212,10 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
+ wake_up_interruptible(&unix_sk(sk)->peer_wait);
+
+ /* attach accepted sock to socket */
+- unix_state_wlock(tsk);
++ unix_state_lock(tsk);
+ newsock->state = SS_CONNECTED;
+ sock_graft(tsk, newsock);
+- unix_state_wunlock(tsk);
++ unix_state_unlock(tsk);
+ return 0;
+
+ out:
+@@ -1209,7 +1242,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
+ }
+
+ u = unix_sk(sk);
+- unix_state_rlock(sk);
++ unix_state_lock(sk);
+ if (!u->addr) {
+ sunaddr->sun_family = AF_UNIX;
+ sunaddr->sun_path[0] = 0;
+@@ -1220,7 +1253,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
+ *uaddr_len = addr->len;
+ memcpy(sunaddr, addr->name, *uaddr_len);
+ }
+- unix_state_runlock(sk);
++ unix_state_unlock(sk);
+ sock_put(sk);
+ out:
+ return err;
+@@ -1338,7 +1371,7 @@ restart:
+ goto out_free;
+ }
+
+- unix_state_rlock(other);
++ unix_state_lock(other);
+ err = -EPERM;
+ if (!unix_may_send(sk, other))
+ goto out_unlock;
+@@ -1348,20 +1381,20 @@ restart:
+ * Check with 1003.1g - what should
+ * datagram error
+ */
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ sock_put(other);
+
+ err = 0;
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ if (unix_peer(sk) == other) {
+ unix_peer(sk)=NULL;
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+
+ unix_dgram_disconnected(sk, other);
+ sock_put(other);
+ err = -ECONNREFUSED;
+ } else {
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ }
+
+ other = NULL;
+@@ -1398,14 +1431,14 @@ restart:
+ }
+
+ skb_queue_tail(&other->sk_receive_queue, skb);
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ other->sk_data_ready(other, len);
+ sock_put(other);
+ scm_destroy(siocb->scm);
+ return len;
+
+ out_unlock:
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ out_free:
+ kfree_skb(skb);
+ out:
+@@ -1495,14 +1528,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
+ goto out_err;
+ }
+
+- unix_state_rlock(other);
++ unix_state_lock(other);
+
+ if (sock_flag(other, SOCK_DEAD) ||
+ (other->sk_shutdown & RCV_SHUTDOWN))
+ goto pipe_err_free;
+
+ skb_queue_tail(&other->sk_receive_queue, skb);
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ other->sk_data_ready(other, size);
+ sent+=size;
+ }
+@@ -1513,7 +1546,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
+ return sent;
+
+ pipe_err_free:
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ kfree_skb(skb);
+ pipe_err:
+ if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL))
+@@ -1642,7 +1675,7 @@ static long unix_stream_data_wait(struct sock * sk, long timeo)
+ {
+ DEFINE_WAIT(wait);
+
+- unix_state_rlock(sk);
++ unix_state_lock(sk);
+
+ for (;;) {
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+@@ -1655,14 +1688,14 @@ static long unix_stream_data_wait(struct sock * sk, long timeo)
+ break;
+
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+- unix_state_runlock(sk);
++ unix_state_unlock(sk);
+ timeo = schedule_timeout(timeo);
+- unix_state_rlock(sk);
++ unix_state_lock(sk);
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ }
+
+ finish_wait(sk->sk_sleep, &wait);
+- unix_state_runlock(sk);
++ unix_state_unlock(sk);
+ return timeo;
+ }
+
+@@ -1817,12 +1850,12 @@ static int unix_shutdown(struct socket *sock, int mode)
+ mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN);
+
+ if (mode) {
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ sk->sk_shutdown |= mode;
+ other=unix_peer(sk);
+ if (other)
+ sock_hold(other);
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ sk->sk_state_change(sk);
+
+ if (other &&
+@@ -1834,9 +1867,9 @@ static int unix_shutdown(struct socket *sock, int mode)
+ peer_mode |= SEND_SHUTDOWN;
+ if (mode&SEND_SHUTDOWN)
+ peer_mode |= RCV_SHUTDOWN;
+- unix_state_wlock(other);
++ unix_state_lock(other);
+ other->sk_shutdown |= peer_mode;
+- unix_state_wunlock(other);
++ unix_state_unlock(other);
+ other->sk_state_change(other);
+ read_lock(&other->sk_callback_lock);
+ if (peer_mode == SHUTDOWN_MASK)
+@@ -1974,7 +2007,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
+ else {
+ struct sock *s = v;
+ struct unix_sock *u = unix_sk(s);
+- unix_state_rlock(s);
++ unix_state_lock(s);
+
+ seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
+ s,
+@@ -2002,7 +2035,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
+ for ( ; i < len; i++)
+ seq_putc(seq, u->addr->name->sun_path[i]);
+ }
+- unix_state_runlock(s);
++ unix_state_unlock(s);
+ seq_putc(seq, '\n');
+ }
+
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 1672cac..632da27 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -198,6 +198,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
+ #define RIRB_INT_MASK 0x05
+
+ /* STATESTS int mask: SD2,SD1,SD0 */
++#define AZX_MAX_CODECS 3
+ #define STATESTS_INT_MASK 0x07
+
+ /* SD_CTL bits */
+@@ -978,7 +979,7 @@ static unsigned int azx_max_codecs[] __devinitdata = {
+ static int __devinit azx_codec_create(struct azx *chip, const char *model)
+ {
+ struct hda_bus_template bus_temp;
+- int c, codecs, err;
++ int c, codecs, audio_codecs, err;
+
+ memset(&bus_temp, 0, sizeof(bus_temp));
+ bus_temp.private_data = chip;
+@@ -990,16 +991,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
+ if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
+ return err;
+
+- codecs = 0;
+- for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
++ codecs = audio_codecs = 0;
++ for (c = 0; c < AZX_MAX_CODECS; c++) {
+ if ((chip->codec_mask & (1 << c)) & probe_mask) {
+- err = snd_hda_codec_new(chip->bus, c, NULL);
++ struct hda_codec *codec;
++ err = snd_hda_codec_new(chip->bus, c, &codec);
+ if (err < 0)
+ continue;
+ codecs++;
++ if (codec->afg)
++ audio_codecs++;
+ }
+ }
+- if (! codecs) {
++ if (!audio_codecs) {
++ /* probe additional slots if no codec is found */
++ for (; c < azx_max_codecs[chip->driver_type]; c++) {
++ if ((chip->codec_mask & (1 << c)) & probe_mask) {
++ err = snd_hda_codec_new(chip->bus, c, NULL);
++ if (err < 0)
++ continue;
++ codecs++;
++ }
++ }
++ }
++ if (!codecs) {
+ snd_printk(KERN_ERR SFX "no codecs initialized\n");
+ return -ENXIO;
+ }
+diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
+index 7073e8e..28684ee 100644
+--- a/sound/soc/codecs/wm8750.c
++++ b/sound/soc/codecs/wm8750.c
+@@ -808,7 +808,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
+ codec->dai = &wm8750_dai;
+ codec->num_dai = 1;
+ codec->reg_cache_size = sizeof(wm8750_reg);
+- codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KRENEL);
++ codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL);
+ if (codec->reg_cache == NULL)
+ return -ENOMEM;
+
+diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
+index 8582620..8fcbe93 100644
+--- a/sound/usb/usbquirks.h
++++ b/sound/usb/usbquirks.h
+@@ -40,6 +40,29 @@
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+
+ /*
++ * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
++ * class matches do not take effect without an explicit ID match.
++ */
++{
++ .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
++ USB_DEVICE_ID_MATCH_INT_CLASS |
++ USB_DEVICE_ID_MATCH_INT_SUBCLASS,
++ .idVendor = 0x046d,
++ .idProduct = 0x08f0,
++ .bInterfaceClass = USB_CLASS_AUDIO,
++ .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
++},
++{
++ .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
++ USB_DEVICE_ID_MATCH_INT_CLASS |
++ USB_DEVICE_ID_MATCH_INT_SUBCLASS,
++ .idVendor = 0x046d,
++ .idProduct = 0x08f6,
++ .bInterfaceClass = USB_CLASS_AUDIO,
++ .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
++},
++
++/*
+ * Yamaha devices
+ */
+
Modified: dists/sid/linux-2.6/debian/patches/series/5
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/5 (original)
+++ dists/sid/linux-2.6/debian/patches/series/5 Mon Jun 11 22:17:49 2007
@@ -1 +1,2 @@
+ bugfix/2.6.21.4
++ bugfix/2.6.21.5
More information about the Kernel-svn-changes
mailing list