diff options
Diffstat (limited to 'packages/linux/linux-ezx-2.6.21/patches/patch-2.6.21.4')
-rw-r--r-- | packages/linux/linux-ezx-2.6.21/patches/patch-2.6.21.4 | 2816 |
1 files changed, 2816 insertions, 0 deletions
diff --git a/packages/linux/linux-ezx-2.6.21/patches/patch-2.6.21.4 b/packages/linux/linux-ezx-2.6.21/patches/patch-2.6.21.4 new file mode 100644 index 0000000000..2c2ed60433 --- /dev/null +++ b/packages/linux/linux-ezx-2.6.21/patches/patch-2.6.21.4 @@ -0,0 +1,2816 @@ +diff --git a/Makefile b/Makefile +index d970cb1..e5c5531 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + VERSION = 2 + PATCHLEVEL = 6 + SUBLEVEL = 21 +-EXTRAVERSION = ++EXTRAVERSION = .4 + NAME = Nocturnal Monster Puppy + + # *DOCUMENTATION* +diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c +index 2409560..7ed141f 100644 +--- a/arch/arm/kernel/traps.c ++++ b/arch/arm/kernel/traps.c +@@ -273,6 +273,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) + struct undef_hook *hook; + siginfo_t info; + void __user *pc; ++ unsigned long flags; + + /* + * According to the ARM ARM, PC is 2 or 4 bytes ahead, +@@ -291,7 +292,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) + get_user(instr, (u32 __user *)pc); + } + +- spin_lock_irq(&undef_lock); ++ spin_lock_irqsave(&undef_lock, flags); + list_for_each_entry(hook, &undef_hook, node) { + if ((instr & hook->instr_mask) == hook->instr_val && + (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { +@@ -301,7 +302,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) + } + } + } +- spin_unlock_irq(&undef_lock); ++ spin_unlock_irqrestore(&undef_lock, flags); + + #ifdef CONFIG_DEBUG_USER + if (user_debug & UDBG_UNDEFINED) { +diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c +index 89ec70e..d907a2a 100644 +--- a/arch/arm/mach-iop13xx/pci.c ++++ b/arch/arm/mach-iop13xx/pci.c +@@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) + << IOP13XX_ATUX_PCIXSR_FUNC_NUM; + __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR); + +- res[0].start = IOP13XX_PCIX_LOWER_IO_PA; ++ res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET; + res[0].end = IOP13XX_PCIX_UPPER_IO_PA; + res[0].name = "IQ81340 ATUX PCI I/O Space"; + res[0].flags = IORESOURCE_IO; +@@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) + res[1].name = "IQ81340 ATUX PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET; +- sys->io_offset = IOP13XX_PCIX_IO_OFFSET; ++ sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA; + break; + case IOP13XX_INIT_ATU_ATUE: + /* Note: the function number field in the PCSR is ro */ +@@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) + + __raw_writel(pcsr, IOP13XX_ATUE_PCSR); + +- res[0].start = IOP13XX_PCIE_LOWER_IO_PA; ++ res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET; + res[0].end = IOP13XX_PCIE_UPPER_IO_PA; + res[0].name = "IQ81340 ATUE PCI I/O Space"; + res[0].flags = IORESOURCE_IO; +@@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) + res[1].name = "IQ81340 ATUE PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET; +- sys->io_offset = IOP13XX_PCIE_IO_OFFSET; ++ sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA; + sys->map_irq = iop13xx_pcie_map_irq; + break; + default: +diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c +index 16300ad..0cc26da 100644 +--- a/arch/arm/plat-iop/time.c ++++ b/arch/arm/plat-iop/time.c +@@ -32,22 +32,22 @@ static unsigned long next_jiffy_time; + + unsigned long iop_gettimeoffset(void) + { +- unsigned long offset, temp1, temp2; ++ unsigned long offset, temp; + + /* enable cp6, if necessary, to avoid taking the overhead of an + * undefined instruction trap + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" +- "ands %1, %0, #(1 << 6)\n\t" ++ "tst %0, #(1 << 6)\n\t" + "orreq %0, %0, #(1 << 6)\n\t" + "mcreq p15, 0, %0, c15, c1, 0\n\t" +-#ifdef CONFIG_XSCALE ++#ifdef CONFIG_CPU_XSCALE + "mrceq p15, 0, %0, c15, c1, 0\n\t" + "moveq %0, %0\n\t" + "subeq pc, pc, #4\n\t" + #endif +- : "=r"(temp1), "=r"(temp2) : : "cc"); ++ : "=r"(temp) : : "cc"); + + offset = next_jiffy_time - read_tcr1(); + +diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +index 837b041..ca3e1d3 100644 +--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c ++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +@@ -341,15 +341,17 @@ static int powernow_acpi_init(void) + pc.val = (unsigned long) acpi_processor_perf->states[0].control; + for (i = 0; i < number_scales; i++) { + u8 fid, vid; +- unsigned int speed; ++ struct acpi_processor_px *state = ++ &acpi_processor_perf->states[i]; ++ unsigned int speed, speed_mhz; + +- pc.val = (unsigned long) acpi_processor_perf->states[i].control; ++ pc.val = (unsigned long) state->control; + dprintk ("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n", + i, +- (u32) acpi_processor_perf->states[i].core_frequency, +- (u32) acpi_processor_perf->states[i].power, +- (u32) acpi_processor_perf->states[i].transition_latency, +- (u32) acpi_processor_perf->states[i].control, ++ (u32) state->core_frequency, ++ (u32) state->power, ++ (u32) state->transition_latency, ++ (u32) state->control, + pc.bits.sgtc); + + vid = pc.bits.vid; +@@ -360,6 +362,18 @@ static int powernow_acpi_init(void) + powernow_table[i].index |= (vid << 8); /* upper 8 bits */ + + speed = powernow_table[i].frequency; ++ speed_mhz = speed / 1000; ++ ++ /* processor_perflib will multiply the MHz value by 1000 to ++ * get a KHz value (e.g. 1266000). However, powernow-k7 works ++ * with true KHz values (e.g. 1266768). To ensure that all ++ * powernow frequencies are available, we must ensure that ++ * ACPI doesn't restrict them, so we round up the MHz value ++ * to ensure that perflib's computed KHz value is greater than ++ * or equal to powernow's KHz value. ++ */ ++ if (speed % 1000 > 0) ++ speed_mhz++; + + if ((fid_codes[fid] % 10)==5) { + if (have_a0 == 1) +@@ -368,10 +382,16 @@ static int powernow_acpi_init(void) + + dprintk (" FID: 0x%x (%d.%dx [%dMHz]) " + "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10, +- fid_codes[fid] % 10, speed/1000, vid, ++ fid_codes[fid] % 10, speed_mhz, vid, + mobile_vid_table[vid]/1000, + mobile_vid_table[vid]%1000); + ++ if (state->core_frequency != speed_mhz) { ++ state->core_frequency = speed_mhz; ++ dprintk(" Corrected ACPI frequency to %d\n", ++ speed_mhz); ++ } ++ + if (latency < pc.bits.sgtc) + latency = pc.bits.sgtc; + +@@ -602,7 +622,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) + result = powernow_acpi_init(); + if (result) { + printk (KERN_INFO PFX "ACPI and legacy methods failed\n"); +- printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml\n"); ++ printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n"); + } + } else { + /* SGTC use the bus clock as timer */ +diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +index fe3b670..e295d87 100644 +--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c ++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +@@ -521,7 +521,7 @@ static int check_supported_cpu(unsigned int cpu) + + if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { + if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || +- ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { ++ ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { + printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); + goto out; + } +diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +index 0fb2a30..575541f 100644 +--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h ++++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +@@ -46,8 +46,8 @@ struct powernow_k8_data { + #define CPUID_XFAM 0x0ff00000 /* extended family */ + #define CPUID_XFAM_K8 0 + #define CPUID_XMOD 0x000f0000 /* extended model */ +-#define CPUID_XMOD_REV_G 0x00060000 +-#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ ++#define CPUID_XMOD_REV_MASK 0x00080000 ++#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ + #define CPUID_USE_XFAM_XMOD 0x00000f00 + #define CPUID_GET_MAX_CAPABILITIES 0x80000000 + #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 +diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c +index fb9bf1e..f56569f 100644 +--- a/arch/sparc64/kernel/of_device.c ++++ b/arch/sparc64/kernel/of_device.c +@@ -508,6 +508,13 @@ static int __init build_one_resource(struct device_node *parent, + return 0; + } + ++ /* When we miss an I/O space match on PCI, just pass it up ++ * to the next PCI bridge and/or controller. ++ */ ++ if (!strcmp(bus->name, "pci") && ++ (addr[0] & 0x03000000) == 0x01000000) ++ return 0; ++ + return 1; + } + +diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c +index 0917c24..3494adf 100644 +--- a/arch/sparc64/kernel/prom.c ++++ b/arch/sparc64/kernel/prom.c +@@ -1555,10 +1555,21 @@ static struct device_node * __init create_node(phandle node, struct device_node + + static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) + { ++ struct device_node *ret = NULL, *prev_sibling = NULL; + struct device_node *dp; + +- dp = create_node(node, parent); +- if (dp) { ++ while (1) { ++ dp = create_node(node, parent); ++ if (!dp) ++ break; ++ ++ if (prev_sibling) ++ prev_sibling->sibling = dp; ++ ++ if (!ret) ++ ret = dp; ++ prev_sibling = dp; ++ + *(*nextp) = dp; + *nextp = &dp->allnext; + +@@ -1567,10 +1578,10 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl + + dp->child = build_tree(dp, prom_getchild(node), nextp); + +- dp->sibling = build_tree(parent, prom_getsibling(node), nextp); ++ node = prom_getsibling(node); + } + +- return dp; ++ return ret; + } + + void __init prom_build_devicetree(void) +diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c +index fc99f7b..8ad7bdb 100644 +--- a/arch/sparc64/kernel/smp.c ++++ b/arch/sparc64/kernel/smp.c +@@ -566,6 +566,9 @@ static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t + unsigned long flags, status; + int cnt, retries, this_cpu, prev_sent, i; + ++ if (cpus_empty(mask)) ++ return; ++ + /* We have to do this whole thing with interrupts fully disabled. + * Otherwise if we send an xcall from interrupt context it will + * corrupt both our mondo block and cpu list state. +diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c +index b43c698..fc9f042 100644 +--- a/arch/x86_64/kernel/vsyscall.c ++++ b/arch/x86_64/kernel/vsyscall.c +@@ -132,7 +132,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) + + /* convert to usecs and add to timespec: */ + tv->tv_usec += nsec_delta / NSEC_PER_USEC; +- while (tv->tv_usec > USEC_PER_SEC) { ++ while (tv->tv_usec >= USEC_PER_SEC) { + tv->tv_sec += 1; + tv->tv_usec -= USEC_PER_SEC; + } +diff --git a/crypto/api.c b/crypto/api.c +index 55af8bb..33734fd 100644 +--- a/crypto/api.c ++++ b/crypto/api.c +@@ -48,8 +48,10 @@ EXPORT_SYMBOL_GPL(crypto_mod_get); + + void crypto_mod_put(struct crypto_alg *alg) + { ++ struct module *module = alg->cra_module; ++ + crypto_alg_put(alg); +- module_put(alg->cra_module); ++ module_put(module); + } + EXPORT_SYMBOL_GPL(crypto_mod_put); + +diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c +index 807c711..d341491 100644 +--- a/drivers/acpi/tables/tbfadt.c ++++ b/drivers/acpi/tables/tbfadt.c +@@ -347,6 +347,20 @@ static void acpi_tb_convert_fadt(void) + acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id; + + } ++ /* ++ * _CST object and C States change notification start with ++ * ACPI 2.0 (FADT r3). Although the field should be Reserved ++ * and 0 before then, some pre-r3 FADT set this field and ++ * it results in SMM-related boot failures. For them, clear it. ++ */ ++ if ((acpi_gbl_FADT.header.revision < 3) && ++ (acpi_gbl_FADT.cst_control != 0)) { ++ ACPI_WARNING((AE_INFO, ++ "Ignoring BIOS FADT r%u C-state control", ++ acpi_gbl_FADT.header.revision)); ++ acpi_gbl_FADT.cst_control = 0; ++ } ++ + } + + /****************************************************************************** +diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c +index 2ffcca0..4d63974 100644 +--- a/drivers/ata/libata-sff.c ++++ b/drivers/ata/libata-sff.c +@@ -557,12 +557,30 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int + int i, p = 0; + void __iomem * const *iomap; + ++ /* Discard disabled ports. Some controllers show their ++ unused channels this way */ ++ if (ata_resources_present(pdev, 0) == 0) ++ ports &= ~ATA_PORT_PRIMARY; ++ if (ata_resources_present(pdev, 1) == 0) ++ ports &= ~ATA_PORT_SECONDARY; ++ + /* iomap BARs */ +- for (i = 0; i < 4; i++) { +- if (pcim_iomap(pdev, i, 0) == NULL) { +- dev_printk(KERN_ERR, &pdev->dev, +- "failed to iomap PCI BAR %d\n", i); +- return NULL; ++ if (ports & ATA_PORT_PRIMARY) { ++ for (i = 0; i <= 1; i++) { ++ if (pcim_iomap(pdev, i, 0) == NULL) { ++ dev_printk(KERN_ERR, &pdev->dev, ++ "failed to iomap PCI BAR %d\n", i); ++ return NULL; ++ } ++ } ++ } ++ if (ports & ATA_PORT_SECONDARY) { ++ for (i = 2; i <= 3; i++) { ++ if (pcim_iomap(pdev, i, 0) == NULL) { ++ dev_printk(KERN_ERR, &pdev->dev, ++ "failed to iomap PCI BAR %d\n", i); ++ return NULL; ++ } + } + } + +@@ -577,13 +595,6 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int + probe_ent->irq = pdev->irq; + probe_ent->irq_flags = IRQF_SHARED; + +- /* Discard disabled ports. Some controllers show their +- unused channels this way */ +- if (ata_resources_present(pdev, 0) == 0) +- ports &= ~ATA_PORT_PRIMARY; +- if (ata_resources_present(pdev, 1) == 0) +- ports &= ~ATA_PORT_SECONDARY; +- + if (ports & ATA_PORT_PRIMARY) { + probe_ent->port[p].cmd_addr = iomap[0]; + probe_ent->port[p].altstatus_addr = +diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c +index 598e6a2..ea6efca 100644 +--- a/drivers/ata/sata_via.c ++++ b/drivers/ata/sata_via.c +@@ -97,6 +97,10 @@ static struct pci_driver svia_pci_driver = { + .name = DRV_NAME, + .id_table = svia_pci_tbl, + .probe = svia_init_one, ++#ifdef CONFIG_PM ++ .suspend = ata_pci_device_suspend, ++ .resume = ata_pci_device_resume, ++#endif + .remove = ata_pci_remove_one, + }; + +@@ -116,6 +120,10 @@ static struct scsi_host_template svia_sht = { + .slave_configure = ata_scsi_slave_config, + .slave_destroy = ata_scsi_slave_destroy, + .bios_param = ata_std_bios_param, ++#ifdef CONFIG_PM ++ .suspend = ata_scsi_device_suspend, ++ .resume = ata_scsi_device_resume, ++#endif + }; + + static const struct ata_port_operations vt6420_sata_ops = { +diff --git a/drivers/base/core.c b/drivers/base/core.c +index d7fcf82..a8dfee2 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -93,6 +93,9 @@ static void device_release(struct kobject * kobj) + { + struct device * dev = to_dev(kobj); + ++ kfree(dev->devt_attr); ++ dev->devt_attr = NULL; ++ + if (dev->release) + dev->release(dev); + else if (dev->type && dev->type->release) +@@ -765,10 +768,8 @@ void device_del(struct device * dev) + + if (parent) + klist_del(&dev->knode_parent); +- if (dev->devt_attr) { ++ if (dev->devt_attr) + device_remove_file(dev, dev->devt_attr); +- kfree(dev->devt_attr); +- } + if (dev->class) { + sysfs_remove_link(&dev->kobj, "subsystem"); + /* If this is not a "fake" compatible device, remove the +diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c +index e221465..cc13ebc 100644 +--- a/drivers/char/ipmi/ipmi_si_intf.c ++++ b/drivers/char/ipmi/ipmi_si_intf.c +@@ -1859,10 +1859,10 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) + + if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + info->io_setup = mem_setup; +- info->io.addr_type = IPMI_IO_ADDR_SPACE; ++ info->io.addr_type = IPMI_MEM_ADDR_SPACE; + } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + info->io_setup = port_setup; +- info->io.addr_type = IPMI_MEM_ADDR_SPACE; ++ info->io.addr_type = IPMI_IO_ADDR_SPACE; + } else { + kfree(info); + printk("ipmi_si: Unknown ACPI I/O Address type\n"); +diff --git a/drivers/char/random.c b/drivers/char/random.c +index b9dc7aa..fa5b95b 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -760,7 +760,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, + + static void extract_buf(struct entropy_store *r, __u8 *out) + { +- int i, x; ++ int i; + __u32 data[16], buf[5 + SHA_WORKSPACE_WORDS]; + + sha_init(buf); +@@ -772,9 +772,11 @@ static void extract_buf(struct entropy_store *r, __u8 *out) + * attempts to find previous ouputs), unless the hash + * function can be inverted. + */ +- for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) { +- sha_transform(buf, (__u8 *)r->pool+i, buf + 5); +- add_entropy_words(r, &buf[x % 5], 1); ++ for (i = 0; i < r->poolinfo->poolwords; i += 16) { ++ /* hash blocks of 16 words = 512 bits */ ++ sha_transform(buf, (__u8 *)(r->pool + i), buf + 5); ++ /* feed back portion of the resulting hash */ ++ add_entropy_words(r, &buf[i % 5], 1); + } + + /* +@@ -782,7 +784,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out) + * portion of the pool while mixing, and hash one + * final time. + */ +- __add_entropy_words(r, &buf[x % 5], 1, data); ++ __add_entropy_words(r, &buf[i % 5], 1, data); + sha_transform(buf, (__u8 *)data, buf + 5); + + /* +@@ -1022,37 +1024,44 @@ random_poll(struct file *file, poll_table * wait) + return mask; + } + +-static ssize_t +-random_write(struct file * file, const char __user * buffer, +- size_t count, loff_t *ppos) ++static int ++write_pool(struct entropy_store *r, const char __user *buffer, size_t count) + { +- int ret = 0; + size_t bytes; + __u32 buf[16]; + const char __user *p = buffer; +- size_t c = count; + +- while (c > 0) { +- bytes = min(c, sizeof(buf)); ++ while (count > 0) { ++ bytes = min(count, sizeof(buf)); ++ if (copy_from_user(&buf, p, bytes)) ++ return -EFAULT; + +- bytes -= copy_from_user(&buf, p, bytes); +- if (!bytes) { +- ret = -EFAULT; +- break; +- } +- c -= bytes; ++ count -= bytes; + p += bytes; + +- add_entropy_words(&input_pool, buf, (bytes + 3) / 4); +- } +- if (p == buffer) { +- return (ssize_t)ret; +- } else { +- struct inode *inode = file->f_path.dentry->d_inode; +- inode->i_mtime = current_fs_time(inode->i_sb); +- mark_inode_dirty(inode); +- return (ssize_t)(p - buffer); ++ add_entropy_words(r, buf, (bytes + 3) / 4); + } ++ ++ return 0; ++} ++ ++static ssize_t ++random_write(struct file * file, const char __user * buffer, ++ size_t count, loff_t *ppos) ++{ ++ size_t ret; ++ struct inode *inode = file->f_path.dentry->d_inode; ++ ++ ret = write_pool(&blocking_pool, buffer, count); ++ if (ret) ++ return ret; ++ ret = write_pool(&nonblocking_pool, buffer, count); ++ if (ret) ++ return ret; ++ ++ inode->i_mtime = current_fs_time(inode->i_sb); ++ mark_inode_dirty(inode); ++ return (ssize_t)count; + } + + static int +@@ -1091,8 +1100,8 @@ random_ioctl(struct inode * inode, struct file * file, + return -EINVAL; + if (get_user(size, p++)) + return -EFAULT; +- retval = random_write(file, (const char __user *) p, +- size, &file->f_pos); ++ retval = write_pool(&input_pool, (const char __user *)p, ++ size); + if (retval < 0) + return retval; + credit_entropy_store(&input_pool, ent_count); +diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c +index 6d3840e..6a86958 100644 +--- a/drivers/crypto/geode-aes.c ++++ b/drivers/crypto/geode-aes.c +@@ -102,10 +102,15 @@ geode_aes_crypt(struct geode_aes_op *op) + u32 flags = 0; + unsigned long iflags; + +- if (op->len == 0 || op->src == op->dst) ++ if (op->len == 0) + return 0; + +- if (op->flags & AES_FLAGS_COHERENT) ++ /* If the source and destination is the same, then ++ * we need to turn on the coherent flags, otherwise ++ * we don't need to worry ++ */ ++ ++ if (op->src == op->dst) + flags |= (AES_CTRL_DCA | AES_CTRL_SCA); + + if (op->dir == AES_DIR_ENCRYPT) +@@ -120,7 +125,7 @@ geode_aes_crypt(struct geode_aes_op *op) + _writefield(AES_WRITEIV0_REG, op->iv); + } + +- if (op->flags & AES_FLAGS_USRKEY) { ++ if (!(op->flags & AES_FLAGS_HIDDENKEY)) { + flags |= AES_CTRL_WRKEY; + _writefield(AES_WRITEKEY0_REG, op->key); + } +@@ -289,6 +294,7 @@ static struct crypto_alg geode_cbc_alg = { + .setkey = geode_setkey, + .encrypt = geode_cbc_encrypt, + .decrypt = geode_cbc_decrypt, ++ .ivsize = AES_IV_LENGTH, + } + } + }; +diff --git a/drivers/crypto/geode-aes.h b/drivers/crypto/geode-aes.h +index 8003a36..f479686 100644 +--- a/drivers/crypto/geode-aes.h ++++ b/drivers/crypto/geode-aes.h +@@ -20,8 +20,7 @@ + #define AES_DIR_DECRYPT 0 + #define AES_DIR_ENCRYPT 1 + +-#define AES_FLAGS_USRKEY (1 << 0) +-#define AES_FLAGS_COHERENT (1 << 1) ++#define AES_FLAGS_HIDDENKEY (1 << 0) + + struct geode_aes_op { + +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index 97ee870..3a95cc5 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -271,21 +271,25 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int + */ + update_head_pos(mirror, r1_bio); + +- if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) { +- /* +- * Set R1BIO_Uptodate in our master bio, so that +- * we will return a good error code for to the higher +- * levels even if IO on some other mirrored buffer fails. +- * +- * The 'master' represents the composite IO operation to +- * user-side. So if something waits for IO, then it will +- * wait for the 'master' bio. ++ if (uptodate) ++ set_bit(R1BIO_Uptodate, &r1_bio->state); ++ else { ++ /* If all other devices have failed, we want to return ++ * the error upwards rather than fail the last device. ++ * Here we redefine "uptodate" to mean "Don't want to retry" + */ +- if (uptodate) +- set_bit(R1BIO_Uptodate, &r1_bio->state); ++ unsigned long flags; ++ spin_lock_irqsave(&conf->device_lock, flags); ++ if (r1_bio->mddev->degraded == conf->raid_disks || ++ (r1_bio->mddev->degraded == conf->raid_disks-1 && ++ !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags))) ++ uptodate = 1; ++ spin_unlock_irqrestore(&conf->device_lock, flags); ++ } + ++ if (uptodate) + raid_end_bio_io(r1_bio); +- } else { ++ else { + /* + * oops, read error: + */ +@@ -992,13 +996,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) + unsigned long flags; + spin_lock_irqsave(&conf->device_lock, flags); + mddev->degraded++; ++ set_bit(Faulty, &rdev->flags); + spin_unlock_irqrestore(&conf->device_lock, flags); + /* + * if recovery is running, make sure it aborts. + */ + set_bit(MD_RECOVERY_ERR, &mddev->recovery); +- } +- set_bit(Faulty, &rdev->flags); ++ } else ++ set_bit(Faulty, &rdev->flags); + set_bit(MD_CHANGE_DEVS, &mddev->flags); + printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" + " Operation continuing on %d devices\n", +diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c +index 85f21b5..2eb5741 100644 +--- a/drivers/message/fusion/mptspi.c ++++ b/drivers/message/fusion/mptspi.c +@@ -726,13 +726,15 @@ static int mptspi_slave_configure(struct scsi_device *sdev) + struct _MPT_SCSI_HOST *hd = + (struct _MPT_SCSI_HOST *)sdev->host->hostdata; + VirtTarget *vtarget = scsi_target(sdev)->hostdata; +- int ret = mptscsih_slave_configure(sdev); ++ int ret; ++ ++ mptspi_initTarget(hd, vtarget, sdev); ++ ++ ret = mptscsih_slave_configure(sdev); + + if (ret) + return ret; + +- mptspi_initTarget(hd, vtarget, sdev); +- + ddvprintk((MYIOC_s_INFO_FMT "id=%d min_period=0x%02x" + " max_offset=0x%02x max_width=%d\n", hd->ioc->name, + sdev->id, spi_min_period(scsi_target(sdev)), +diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig +index a3d46ea..32a3003 100644 +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -2929,11 +2929,6 @@ endif #NETDEVICES + config NETPOLL + def_bool NETCONSOLE + +-config NETPOLL_RX +- bool "Netpoll support for trapping incoming packets" +- default n +- depends on NETPOLL +- + config NETPOLL_TRAP + bool "Netpoll traffic trapping" + default n +diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c +index e85f5ec..5006c67 100644 +--- a/drivers/net/bnx2.c ++++ b/drivers/net/bnx2.c +@@ -54,8 +54,8 @@ + + #define DRV_MODULE_NAME "bnx2" + #define PFX DRV_MODULE_NAME ": " +-#define DRV_MODULE_VERSION "1.5.8" +-#define DRV_MODULE_RELDATE "April 24, 2007" ++#define DRV_MODULE_VERSION "1.5.8.1" ++#define DRV_MODULE_RELDATE "May 7, 2007" + + #define RUN_AT(x) (jiffies + (x)) + +@@ -4510,8 +4510,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) + vlan_tag_flags |= + (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); + } +- if ((mss = skb_shinfo(skb)->gso_size) && +- (skb->len > (bp->dev->mtu + ETH_HLEN))) { ++ if ((mss = skb_shinfo(skb)->gso_size)) { + u32 tcp_opt_len, ip_tcp_len; + + if (skb_header_cloned(skb) && +@@ -5565,6 +5564,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + case SIOCGMIIREG: { + u32 mii_regval; + ++ if (!netif_running(dev)) ++ return -EAGAIN; ++ + spin_lock_bh(&bp->phy_lock); + err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval); + spin_unlock_bh(&bp->phy_lock); +@@ -5578,6 +5580,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + ++ if (!netif_running(dev)) ++ return -EAGAIN; ++ + spin_lock_bh(&bp->phy_lock); + err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in); + spin_unlock_bh(&bp->phy_lock); +@@ -6143,6 +6148,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) + reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; + bnx2_reset_chip(bp, reset_code); + bnx2_free_skbs(bp); ++ pci_save_state(pdev); + bnx2_set_power_state(bp, pci_choose_state(pdev, state)); + return 0; + } +@@ -6156,6 +6162,7 @@ bnx2_resume(struct pci_dev *pdev) + if (!netif_running(dev)) + return 0; + ++ pci_restore_state(pdev); + bnx2_set_power_state(bp, PCI_D0); + netif_device_attach(dev); + bnx2_init_nic(bp); +diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c +index b2a3b19..ce547af 100644 +--- a/drivers/net/sis900.c ++++ b/drivers/net/sis900.c +@@ -1754,6 +1754,7 @@ static int sis900_rx(struct net_device *net_dev) + sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; + } else { + struct sk_buff * skb; ++ struct sk_buff * rx_skb; + + pci_unmap_single(sis_priv->pci_dev, + sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, +@@ -1787,10 +1788,10 @@ static int sis900_rx(struct net_device *net_dev) + } + + /* give the socket buffer to upper layers */ +- skb = sis_priv->rx_skbuff[entry]; +- skb_put(skb, rx_size); +- skb->protocol = eth_type_trans(skb, net_dev); +- netif_rx(skb); ++ rx_skb = sis_priv->rx_skbuff[entry]; ++ skb_put(rx_skb, rx_size); ++ rx_skb->protocol = eth_type_trans(rx_skb, net_dev); ++ netif_rx(rx_skb); + + /* some network statistics */ + if ((rx_status & BCAST) == MCAST) +diff --git a/drivers/net/skge.c b/drivers/net/skge.c +index d476a3c..5ef9023 100644 +--- a/drivers/net/skge.c ++++ b/drivers/net/skge.c +@@ -135,10 +135,13 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, + /* Wake on Lan only supported on Yukon chips with rev 1 or above */ + static u32 wol_supported(const struct skge_hw *hw) + { +- if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0) +- return WAKE_MAGIC | WAKE_PHY; +- else ++ if (hw->chip_id == CHIP_ID_GENESIS) ++ return 0; ++ ++ if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) + return 0; ++ ++ return WAKE_MAGIC | WAKE_PHY; + } + + static u32 pci_wake_enabled(struct pci_dev *dev) +@@ -3583,7 +3586,9 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, + skge->duplex = -1; + skge->speed = -1; + skge->advertising = skge_supported_modes(hw); +- skge->wol = pci_wake_enabled(hw->pdev) ? wol_supported(hw) : 0; ++ ++ if (pci_wake_enabled(hw->pdev)) ++ skge->wol = wol_supported(hw) & WAKE_MAGIC; + + hw->dev[port] = dev; + +@@ -3789,6 +3794,9 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) + struct skge_hw *hw = pci_get_drvdata(pdev); + int i, err, wol = 0; + ++ if (!hw) ++ return 0; ++ + err = pci_save_state(pdev); + if (err) + return err; +@@ -3817,6 +3825,9 @@ static int skge_resume(struct pci_dev *pdev) + struct skge_hw *hw = pci_get_drvdata(pdev); + int i, err; + ++ if (!hw) ++ return 0; ++ + err = pci_set_power_state(pdev, PCI_D0); + if (err) + goto out; +@@ -3855,6 +3866,9 @@ static void skge_shutdown(struct pci_dev *pdev) + struct skge_hw *hw = pci_get_drvdata(pdev); + int i, wol = 0; + ++ if (!hw) ++ return; ++ + for (i = 0; i < hw->ports; i++) { + struct net_device *dev = hw->dev[i]; + struct skge_port *skge = netdev_priv(dev); +diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c +index ac36152..b6b444b 100644 +--- a/drivers/net/sky2.c ++++ b/drivers/net/sky2.c +@@ -123,16 +123,13 @@ static const struct pci_device_id sky2_id_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ +-#ifdef broken +- /* This device causes data corruption problems that are not resolved */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ +-#endif + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ +- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ ++// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ + { 0 } + }; + +@@ -3722,6 +3719,7 @@ err_out_free_regions: + pci_release_regions(pdev); + pci_disable_device(pdev); + err_out: ++ pci_set_drvdata(pdev, NULL); + return err; + } + +@@ -3774,6 +3772,9 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) + struct sky2_hw *hw = pci_get_drvdata(pdev); + int i, wol = 0; + ++ if (!hw) ++ return 0; ++ + del_timer_sync(&hw->idle_timer); + netif_poll_disable(hw->dev[0]); + +@@ -3805,6 +3806,9 @@ static int sky2_resume(struct pci_dev *pdev) + struct sky2_hw *hw = pci_get_drvdata(pdev); + int i, err; + ++ if (!hw) ++ return 0; ++ + err = pci_set_power_state(pdev, PCI_D0); + if (err) + goto out; +@@ -3851,6 +3855,9 @@ static void sky2_shutdown(struct pci_dev *pdev) + struct sky2_hw *hw = pci_get_drvdata(pdev); + int i, wol = 0; + ++ if (!hw) ++ return; ++ + del_timer_sync(&hw->idle_timer); + netif_poll_disable(hw->dev[0]); + +diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c +index c956141..0b89812 100644 +--- a/drivers/net/smc911x.c ++++ b/drivers/net/smc911x.c +@@ -499,7 +499,7 @@ static inline void smc911x_rcv(struct net_device *dev) + SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_)); + SMC_PULL_DATA(data, pkt_len+2+3); + +- DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name,); ++ DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name); + PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64); + dev->last_rx = jiffies; + skb->dev = dev; +diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c +index 256969e..3d20115 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" +-#define DRV_MODULE_RELDATE "March 23, 2007" ++#define DRV_MODULE_VERSION "3.75.1" ++#define DRV_MODULE_RELDATE "May 7, 2007" + + #define TG3_DEF_MAC_MODE 0 + #define TG3_DEF_RX_MODE 0 +@@ -3895,8 +3895,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) + entry = tp->tx_prod; + base_flags = 0; + mss = 0; +- if (skb->len > (tp->dev->mtu + ETH_HLEN) && +- (mss = skb_shinfo(skb)->gso_size) != 0) { ++ if ((mss = skb_shinfo(skb)->gso_size) != 0) { + int tcp_opt_len, ip_tcp_len; + + if (skb_header_cloned(skb) && +@@ -4053,8 +4052,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) + if (skb->ip_summed == CHECKSUM_PARTIAL) + base_flags |= TXD_FLAG_TCPUDP_CSUM; + mss = 0; +- if (skb->len > (tp->dev->mtu + ETH_HLEN) && +- (mss = skb_shinfo(skb)->gso_size) != 0) { ++ if ((mss = skb_shinfo(skb)->gso_size) != 0) { + int tcp_opt_len, ip_tcp_len, hdr_len; + + if (skb_header_cloned(skb) && +@@ -5936,7 +5934,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp) + + + /* tp->lock is held. */ +-static void __tg3_set_mac_addr(struct tg3 *tp) ++static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1) + { + u32 addr_high, addr_low; + int i; +@@ -5948,6 +5946,8 @@ static void __tg3_set_mac_addr(struct tg3 *tp) + (tp->dev->dev_addr[4] << 8) | + (tp->dev->dev_addr[5] << 0)); + for (i = 0; i < 4; i++) { ++ if (i == 1 && skip_mac_1) ++ continue; + tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high); + tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); + } +@@ -5974,7 +5974,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) + { + struct tg3 *tp = netdev_priv(dev); + struct sockaddr *addr = p; +- int err = 0; ++ int err = 0, skip_mac_1 = 0; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; +@@ -5985,22 +5985,21 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) + return 0; + + if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { +- /* Reset chip so that ASF can re-init any MAC addresses it +- * needs. +- */ +- tg3_netif_stop(tp); +- tg3_full_lock(tp, 1); ++ u32 addr0_high, addr0_low, addr1_high, addr1_low; + +- tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); +- err = tg3_restart_hw(tp, 0); +- if (!err) +- tg3_netif_start(tp); +- tg3_full_unlock(tp); +- } else { +- spin_lock_bh(&tp->lock); +- __tg3_set_mac_addr(tp); +- spin_unlock_bh(&tp->lock); ++ addr0_high = tr32(MAC_ADDR_0_HIGH); ++ addr0_low = tr32(MAC_ADDR_0_LOW); ++ addr1_high = tr32(MAC_ADDR_1_HIGH); ++ addr1_low = tr32(MAC_ADDR_1_LOW); ++ ++ /* Skip MAC addr 1 if ASF is using it. */ ++ if ((addr0_high != addr1_high || addr0_low != addr1_low) && ++ !(addr1_high == 0 && addr1_low == 0)) ++ skip_mac_1 = 1; + } ++ spin_lock_bh(&tp->lock); ++ __tg3_set_mac_addr(tp, skip_mac_1); ++ spin_unlock_bh(&tp->lock); + + return err; + } +@@ -6317,7 +6316,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) + tp->rx_jumbo_ptr); + + /* Initialize MAC address and backoff seed. */ +- __tg3_set_mac_addr(tp); ++ __tg3_set_mac_addr(tp, 0); + + /* MTU + ethernet header + FCS + optional VLAN tag */ + tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8); +@@ -6348,8 +6347,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) + tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) { + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE && +- (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 || +- tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) { ++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; + } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) { +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 65d6f23..5af9125 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -1737,18 +1737,20 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, + quirk_nvidia_ck804_pcie_aer_ext_cap); + + #ifdef CONFIG_PCI_MSI +-/* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely +- * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually +- * some other busses controlled by the chipset even if Linux is not aware of it. +- * Instead of setting the flag on all busses in the machine, simply disable MSI +- * globally. ++/* Some chipsets do not support MSI. We cannot easily rely on setting ++ * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually ++ * some other busses controlled by the chipset even if Linux is not ++ * aware of it. Instead of setting the flag on all busses in the ++ * machine, simply disable MSI globally. + */ +-static void __init quirk_svw_msi(struct pci_dev *dev) ++static void __init quirk_disable_all_msi(struct pci_dev *dev) + { + pci_no_msi(); + printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n"); + } +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi); ++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); + + /* 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/serial/sunhv.c b/drivers/serial/sunhv.c +index 40d4856..c3a6bd2 100644 +--- a/drivers/serial/sunhv.c ++++ b/drivers/serial/sunhv.c +@@ -493,6 +493,10 @@ static struct of_device_id hv_match[] = { + .name = "console", + .compatible = "qcn", + }, ++ { ++ .name = "console", ++ .compatible = "SUNW,sun4v-console", ++ }, + {}, + }; + MODULE_DEVICE_TABLE(of, hv_match); +diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c +index 3dfa3e4..3257d94 100644 +--- a/drivers/usb/atm/cxacru.c ++++ b/drivers/usb/atm/cxacru.c +@@ -146,6 +146,12 @@ enum cxacru_info_idx { + CXINF_MAX = 0x1c, + }; + ++enum poll_state { ++ CX_INIT, ++ CX_POLLING, ++ CX_ABORT ++}; ++ + struct cxacru_modem_type { + u32 pll_f_clk; + u32 pll_b_clk; +@@ -159,6 +165,8 @@ struct cxacru_data { + + int line_status; + struct delayed_work poll_work; ++ struct mutex poll_state_serialize; ++ enum poll_state poll_state; + + /* contol handles */ + struct mutex cm_serialize; +@@ -356,7 +364,7 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, + /* + struct atm_dev *atm_dev = usbatm_instance->atm_dev; + */ +- int ret; ++ int ret, start_polling = 1; + + dbg("cxacru_atm_start"); + +@@ -376,7 +384,15 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, + } + + /* Start status polling */ +- cxacru_poll_status(&instance->poll_work.work); ++ mutex_lock(&instance->poll_state_serialize); ++ if (instance->poll_state == CX_INIT) ++ instance->poll_state = CX_POLLING; ++ else /* poll_state == CX_ABORT */ ++ start_polling = 0; ++ mutex_unlock(&instance->poll_state_serialize); ++ ++ if (start_polling) ++ cxacru_poll_status(&instance->poll_work.work); + return 0; + } + +@@ -685,6 +701,9 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, + instance->usbatm = usbatm_instance; + instance->modem_type = (struct cxacru_modem_type *) id->driver_info; + ++ mutex_init(&instance->poll_state_serialize); ++ instance->poll_state = CX_INIT; ++ + instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); + if (!instance->rcv_buf) { + dbg("cxacru_bind: no memory for rcv_buf"); +@@ -744,6 +763,7 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, + struct usb_interface *intf) + { + struct cxacru_data *instance = usbatm_instance->driver_data; ++ int stop_polling = 1; + + dbg("cxacru_unbind entered"); + +@@ -752,8 +772,20 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, + return; + } + +- while (!cancel_delayed_work(&instance->poll_work)) +- flush_scheduled_work(); ++ mutex_lock(&instance->poll_state_serialize); ++ if (instance->poll_state != CX_POLLING) { ++ /* Polling hasn't started yet and with ++ * the mutex locked it can be prevented ++ * from starting. ++ */ ++ instance->poll_state = CX_ABORT; ++ stop_polling = 0; ++ } ++ mutex_unlock(&instance->poll_state_serialize); ++ ++ if (stop_polling) ++ while (!cancel_delayed_work(&instance->poll_work)) ++ flush_scheduled_work(); + + usb_kill_urb(instance->snd_urb); + usb_kill_urb(instance->rcv_urb); +diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c +index a8b3d66..488d61b 100644 +--- a/drivers/usb/input/hiddev.c ++++ b/drivers/usb/input/hiddev.c +@@ -51,6 +51,7 @@ struct hiddev { + wait_queue_head_t wait; + struct hid_device *hid; + struct list_head list; ++ spinlock_t list_lock; + }; + + struct hiddev_list { +@@ -161,7 +162,9 @@ static void hiddev_send_event(struct hid_device *hid, + { + struct hiddev *hiddev = hid->hiddev; + struct hiddev_list *list; ++ unsigned long flags; + ++ spin_lock_irqsave(&hiddev->list_lock, flags); + list_for_each_entry(list, &hiddev->list, node) { + if (uref->field_index != HID_FIELD_INDEX_NONE || + (list->flags & HIDDEV_FLAG_REPORT) != 0) { +@@ -171,6 +174,7 @@ static void hiddev_send_event(struct hid_device *hid, + kill_fasync(&list->fasync, SIGIO, POLL_IN); + } + } ++ spin_unlock_irqrestore(&hiddev->list_lock, flags); + + wake_up_interruptible(&hiddev->wait); + } +@@ -235,9 +239,13 @@ static int hiddev_fasync(int fd, struct file *file, int on) + static int hiddev_release(struct inode * inode, struct file * file) + { + struct hiddev_list *list = file->private_data; ++ unsigned long flags; + + hiddev_fasync(-1, file, 0); ++ ++ spin_lock_irqsave(&list->hiddev->list_lock, flags); + list_del(&list->node); ++ spin_unlock_irqrestore(&list->hiddev->list_lock, flags); + + if (!--list->hiddev->open) { + if (list->hiddev->exist) +@@ -257,6 +265,7 @@ static int hiddev_release(struct inode * inode, struct file * file) + static int hiddev_open(struct inode *inode, struct file *file) + { + struct hiddev_list *list; ++ unsigned long flags; + + int i = iminor(inode) - HIDDEV_MINOR_BASE; + +@@ -267,7 +276,11 @@ static int hiddev_open(struct inode *inode, struct file *file) + return -ENOMEM; + + list->hiddev = hiddev_table[i]; ++ ++ spin_lock_irqsave(&list->hiddev->list_lock, flags); + list_add_tail(&list->node, &hiddev_table[i]->list); ++ spin_unlock_irqrestore(&list->hiddev->list_lock, flags); ++ + file->private_data = list; + + if (!list->hiddev->open++) +@@ -773,6 +786,7 @@ int hiddev_connect(struct hid_device *hid) + + init_waitqueue_head(&hiddev->wait); + INIT_LIST_HEAD(&hiddev->list); ++ spin_lock_init(&hiddev->list_lock); + hiddev->hid = hid; + hiddev->exist = 1; + +diff --git a/fs/fat/dir.c b/fs/fat/dir.c +index c16af24..ccf161d 100644 +--- a/fs/fat/dir.c ++++ b/fs/fat/dir.c +@@ -422,7 +422,7 @@ EODir: + EXPORT_SYMBOL_GPL(fat_search_long); + + struct fat_ioctl_filldir_callback { +- struct dirent __user *dirent; ++ void __user *dirent; + int result; + /* for dir ioctl */ + const char *longname; +@@ -647,62 +647,85 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) + return __fat_readdir(inode, filp, dirent, filldir, 0, 0); + } + +-static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, +- loff_t offset, u64 ino, unsigned int d_type) ++#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \ ++static int func(void *__buf, const char *name, int name_len, \ ++ loff_t offset, u64 ino, unsigned int d_type) \ ++{ \ ++ struct fat_ioctl_filldir_callback *buf = __buf; \ ++ struct dirent_type __user *d1 = buf->dirent; \ ++ struct dirent_type __user *d2 = d1 + 1; \ ++ \ ++ if (buf->result) \ ++ return -EINVAL; \ ++ buf->result++; \ ++ \ ++ if (name != NULL) { \ ++ /* dirent has only short name */ \ ++ if (name_len >= sizeof(d1->d_name)) \ ++ name_len = sizeof(d1->d_name) - 1; \ ++ \ ++ if (put_user(0, d2->d_name) || \ ++ put_user(0, &d2->d_reclen) || \ ++ copy_to_user(d1->d_name, name, name_len) || \ ++ put_user(0, d1->d_name + name_len) || \ ++ put_user(name_len, &d1->d_reclen)) \ ++ goto efault; \ ++ } else { \ ++ /* dirent has short and long name */ \ ++ const char *longname = buf->longname; \ ++ int long_len = buf->long_len; \ ++ const char *shortname = buf->shortname; \ ++ int short_len = buf->short_len; \ ++ \ ++ if (long_len >= sizeof(d1->d_name)) \ ++ long_len = sizeof(d1->d_name) - 1; \ ++ if (short_len >= sizeof(d1->d_name)) \ ++ short_len = sizeof(d1->d_name) - 1; \ ++ \ ++ if (copy_to_user(d2->d_name, longname, long_len) || \ ++ put_user(0, d2->d_name + long_len) || \ ++ put_user(long_len, &d2->d_reclen) || \ ++ put_user(ino, &d2->d_ino) || \ ++ put_user(offset, &d2->d_off) || \ ++ copy_to_user(d1->d_name, shortname, short_len) || \ ++ put_user(0, d1->d_name + short_len) || \ ++ put_user(short_len, &d1->d_reclen)) \ ++ goto efault; \ ++ } \ ++ return 0; \ ++efault: \ ++ buf->result = -EFAULT; \ ++ return -EFAULT; \ ++} ++ ++FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, dirent) ++ ++static int fat_ioctl_readdir(struct inode *inode, struct file *filp, ++ void __user *dirent, filldir_t filldir, ++ int short_only, int both) + { +- struct fat_ioctl_filldir_callback *buf = __buf; +- struct dirent __user *d1 = buf->dirent; +- struct dirent __user *d2 = d1 + 1; +- +- if (buf->result) +- return -EINVAL; +- buf->result++; +- +- if (name != NULL) { +- /* dirent has only short name */ +- if (name_len >= sizeof(d1->d_name)) +- name_len = sizeof(d1->d_name) - 1; +- +- if (put_user(0, d2->d_name) || +- put_user(0, &d2->d_reclen) || +- copy_to_user(d1->d_name, name, name_len) || +- put_user(0, d1->d_name + name_len) || +- put_user(name_len, &d1->d_reclen)) +- goto efault; +- } else { +- /* dirent has short and long name */ +- const char *longname = buf->longname; +- int long_len = buf->long_len; +- const char *shortname = buf->shortname; +- int short_len = buf->short_len; +- +- if (long_len >= sizeof(d1->d_name)) +- long_len = sizeof(d1->d_name) - 1; +- if (short_len >= sizeof(d1->d_name)) +- short_len = sizeof(d1->d_name) - 1; +- +- if (copy_to_user(d2->d_name, longname, long_len) || +- put_user(0, d2->d_name + long_len) || +- put_user(long_len, &d2->d_reclen) || +- put_user(ino, &d2->d_ino) || +- put_user(offset, &d2->d_off) || +- copy_to_user(d1->d_name, shortname, short_len) || +- put_user(0, d1->d_name + short_len) || +- put_user(short_len, &d1->d_reclen)) +- goto efault; ++ struct fat_ioctl_filldir_callback buf; ++ int ret; ++ ++ buf.dirent = dirent; ++ buf.result = 0; ++ mutex_lock(&inode->i_mutex); ++ ret = -ENOENT; ++ if (!IS_DEADDIR(inode)) { ++ ret = __fat_readdir(inode, filp, &buf, filldir, ++ short_only, both); + } +- return 0; +-efault: +- buf->result = -EFAULT; +- return -EFAULT; ++ mutex_unlock(&inode->i_mutex); ++ if (ret >= 0) ++ ret = buf.result; ++ return ret; + } + +-static int fat_dir_ioctl(struct inode * inode, struct file * filp, +- unsigned int cmd, unsigned long arg) ++static int fat_dir_ioctl(struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg) + { +- struct fat_ioctl_filldir_callback buf; +- struct dirent __user *d1; +- int ret, short_only, both; ++ struct dirent __user *d1 = (struct dirent __user *)arg; ++ int short_only, both; + + switch (cmd) { + case VFAT_IOCTL_READDIR_SHORT: +@@ -717,7 +740,6 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, + return fat_generic_ioctl(inode, filp, cmd, arg); + } + +- d1 = (struct dirent __user *)arg; + if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2]))) + return -EFAULT; + /* +@@ -728,69 +750,48 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, + if (put_user(0, &d1->d_reclen)) + return -EFAULT; + +- buf.dirent = d1; +- buf.result = 0; +- mutex_lock(&inode->i_mutex); +- ret = -ENOENT; +- if (!IS_DEADDIR(inode)) { +- ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir, +- short_only, both); +- } +- mutex_unlock(&inode->i_mutex); +- if (ret >= 0) +- ret = buf.result; +- return ret; ++ return fat_ioctl_readdir(inode, filp, d1, fat_ioctl_filldir, ++ short_only, both); + } + + #ifdef CONFIG_COMPAT + #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) + #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) + +-static long fat_compat_put_dirent32(struct dirent *d, +- struct compat_dirent __user *d32) +-{ +- if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) +- return -EFAULT; +- +- __put_user(d->d_ino, &d32->d_ino); +- __put_user(d->d_off, &d32->d_off); +- __put_user(d->d_reclen, &d32->d_reclen); +- if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) +- return -EFAULT; ++FAT_IOCTL_FILLDIR_FUNC(fat_compat_ioctl_filldir, compat_dirent) + +- return 0; +-} +- +-static long fat_compat_dir_ioctl(struct file *file, unsigned cmd, ++static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd, + unsigned long arg) + { +- struct compat_dirent __user *p = compat_ptr(arg); +- int ret; +- mm_segment_t oldfs = get_fs(); +- struct dirent d[2]; ++ struct inode *inode = filp->f_path.dentry->d_inode; ++ struct compat_dirent __user *d1 = compat_ptr(arg); ++ int short_only, both; + + switch (cmd) { +- case VFAT_IOCTL_READDIR_BOTH32: +- cmd = VFAT_IOCTL_READDIR_BOTH; +- break; + case VFAT_IOCTL_READDIR_SHORT32: +- cmd = VFAT_IOCTL_READDIR_SHORT; ++ short_only = 1; ++ both = 0; ++ break; ++ case VFAT_IOCTL_READDIR_BOTH32: ++ short_only = 0; ++ both = 1; + break; + default: + return -ENOIOCTLCMD; + } + +- set_fs(KERNEL_DS); +- lock_kernel(); +- ret = fat_dir_ioctl(file->f_path.dentry->d_inode, file, +- cmd, (unsigned long) &d); +- unlock_kernel(); +- set_fs(oldfs); +- if (ret >= 0) { +- ret |= fat_compat_put_dirent32(&d[0], p); +- ret |= fat_compat_put_dirent32(&d[1], p + 1); +- } +- return ret; ++ if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2]))) ++ return -EFAULT; ++ /* ++ * Yes, we don't need this put_user() absolutely. However old ++ * code didn't return the right value. So, app use this value, ++ * in order to check whether it is EOF. ++ */ ++ if (put_user(0, &d1->d_reclen)) ++ return -EFAULT; ++ ++ return fat_ioctl_readdir(inode, filp, d1, fat_compat_ioctl_filldir, ++ short_only, both); + } + #endif /* CONFIG_COMPAT */ + +diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c +index 5065baa..3760d02 100644 +--- a/fs/jfs/jfs_logmgr.c ++++ b/fs/jfs/jfs_logmgr.c +@@ -2354,12 +2354,13 @@ int jfsIOWait(void *arg) + lbmStartIO(bp); + spin_lock_irq(&log_redrive_lock); + } +- spin_unlock_irq(&log_redrive_lock); + + if (freezing(current)) { ++ spin_unlock_irq(&log_redrive_lock); + refrigerator(); + } else { + set_current_state(TASK_INTERRUPTIBLE); ++ spin_unlock_irq(&log_redrive_lock); + schedule(); + current->state = TASK_RUNNING; + } +diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c +index 6f24768..79bd03b 100644 +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -469,6 +469,13 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) + nd.dentry = NULL; + exp.ex_path = NULL; + ++ /* fs locations */ ++ exp.ex_fslocs.locations = NULL; ++ exp.ex_fslocs.locations_count = 0; ++ exp.ex_fslocs.migrated = 0; ++ ++ exp.ex_uuid = NULL; ++ + if (mesg[mlen-1] != '\n') + return -EINVAL; + mesg[mlen-1] = 0; +@@ -509,13 +516,6 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) + if (exp.h.expiry_time == 0) + goto out; + +- /* fs locations */ +- exp.ex_fslocs.locations = NULL; +- exp.ex_fslocs.locations_count = 0; +- exp.ex_fslocs.migrated = 0; +- +- exp.ex_uuid = NULL; +- + /* flags */ + err = get_int(&mesg, &an_int); + if (err == -ENOENT) +diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c +index c8178b7..2cac562 100644 +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -68,7 +68,7 @@ static struct dentry *get_xa_root(struct super_block *sb, int flags) + if (!privroot) + return ERR_PTR(-ENODATA); + +- mutex_lock(&privroot->d_inode->i_mutex); ++ mutex_lock_nested(&privroot->d_inode->i_mutex, I_MUTEX_XATTR); + if (REISERFS_SB(sb)->xattr_root) { + xaroot = dget(REISERFS_SB(sb)->xattr_root); + goto out; +diff --git a/fs/udf/namei.c b/fs/udf/namei.c +index fe361cd..b254375 100644 +--- a/fs/udf/namei.c ++++ b/fs/udf/namei.c +@@ -878,7 +878,7 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) + inode->i_nlink); + clear_nlink(inode); + inode->i_size = 0; +- inode_dec_link_count(inode); ++ inode_dec_link_count(dir); + inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); + mark_inode_dirty(dir); + +diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h +index d26b755..74d7498 100644 +--- a/include/asm-arm/arch-iop13xx/iop13xx.h ++++ b/include/asm-arm/arch-iop13xx/iop13xx.h +@@ -27,19 +27,24 @@ static inline int iop13xx_cpu_id(void) + #define IOP13XX_PCI_OFFSET IOP13XX_MAX_RAM_SIZE + + /* PCI MAP +- * 0x0000.0000 - 0x8000.0000 1:1 mapping with Physical RAM +- * 0x8000.0000 - 0x8800.0000 PCIX/PCIE memory window (128MB) +-*/ ++ * bus range cpu phys cpu virt note ++ * 0x0000.0000 + 2GB (n/a) (n/a) inbound, 1:1 mapping with Physical RAM ++ * 0x8000.0000 + 928M 0x1.8000.0000 (ioremap) PCIX outbound memory window ++ * 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window ++ * ++ * IO MAP ++ * 0x1000 + 64K 0x0.fffb.1000 0xfec6.1000 PCIX outbound i/o window ++ * 0x1000 + 64K 0x0.fffd.1000 0xfed7.1000 PCIE outbound i/o window ++ */ + #define IOP13XX_PCIX_IO_WINDOW_SIZE 0x10000UL + #define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL + #define IOP13XX_PCIX_LOWER_IO_VA 0xfec60000UL +-#define IOP13XX_PCIX_LOWER_IO_BA 0x0fff0000UL ++#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */ ++#define IOP13XX_PCIX_IO_BUS_OFFSET 0x1000UL + #define IOP13XX_PCIX_UPPER_IO_PA (IOP13XX_PCIX_LOWER_IO_PA +\ + IOP13XX_PCIX_IO_WINDOW_SIZE - 1) + #define IOP13XX_PCIX_UPPER_IO_VA (IOP13XX_PCIX_LOWER_IO_VA +\ + IOP13XX_PCIX_IO_WINDOW_SIZE - 1) +-#define IOP13XX_PCIX_IO_OFFSET (IOP13XX_PCIX_LOWER_IO_VA -\ +- IOP13XX_PCIX_LOWER_IO_BA) + #define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\ + (IOP13XX_PCIX_LOWER_IO_PA\ + - IOP13XX_PCIX_LOWER_IO_VA)) +@@ -65,15 +70,14 @@ static inline int iop13xx_cpu_id(void) + #define IOP13XX_PCIE_IO_WINDOW_SIZE 0x10000UL + #define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL + #define IOP13XX_PCIE_LOWER_IO_VA 0xfed70000UL +-#define IOP13XX_PCIE_LOWER_IO_BA 0x0fff0000UL ++#define IOP13XX_PCIE_LOWER_IO_BA 0x0UL /* OIOTVR */ ++#define IOP13XX_PCIE_IO_BUS_OFFSET 0x1000UL + #define IOP13XX_PCIE_UPPER_IO_PA (IOP13XX_PCIE_LOWER_IO_PA +\ + IOP13XX_PCIE_IO_WINDOW_SIZE - 1) + #define IOP13XX_PCIE_UPPER_IO_VA (IOP13XX_PCIE_LOWER_IO_VA +\ + IOP13XX_PCIE_IO_WINDOW_SIZE - 1) + #define IOP13XX_PCIE_UPPER_IO_BA (IOP13XX_PCIE_LOWER_IO_BA +\ + IOP13XX_PCIE_IO_WINDOW_SIZE - 1) +-#define IOP13XX_PCIE_IO_OFFSET (IOP13XX_PCIE_LOWER_IO_VA -\ +- IOP13XX_PCIE_LOWER_IO_BA) + #define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\ + (IOP13XX_PCIE_LOWER_IO_PA\ + - IOP13XX_PCIE_LOWER_IO_VA)) +diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h +index e01b805..26ec046 100644 +--- a/include/asm-sparc64/openprom.h ++++ b/include/asm-sparc64/openprom.h +@@ -177,7 +177,7 @@ struct linux_nodeops { + /* More fun PROM structures for device probing. */ + #define PROMREG_MAX 24 + #define PROMVADDR_MAX 16 +-#define PROMINTR_MAX 15 ++#define PROMINTR_MAX 32 + + struct linux_prom_registers { + unsigned which_io; /* hi part of physical address */ +diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h +index daa4940..bf92c26 100644 +--- a/include/linux/clocksource.h ++++ b/include/linux/clocksource.h +@@ -48,6 +48,7 @@ struct clocksource; + * @shift: cycle to nanosecond divisor (power of two) + * @flags: flags describing special properties + * @vread: vsyscall based read ++ * @resume: resume function for the clocksource, if necessary + * @cycle_interval: Used internally by timekeeping core, please ignore. + * @xtime_interval: Used internally by timekeeping core, please ignore. + */ +@@ -61,6 +62,7 @@ struct clocksource { + u32 shift; + unsigned long flags; + cycle_t (*vread)(void); ++ void (*resume)(void); + + /* timekeeping specific data, ignore */ + cycle_t cycle_last, cycle_interval; +@@ -198,6 +200,7 @@ static inline void clocksource_calculate_interval(struct clocksource *c, + extern int clocksource_register(struct clocksource*); + extern struct clocksource* clocksource_get_next(void); + extern void clocksource_change_rating(struct clocksource *cs, int rating); ++extern void clocksource_resume(void); + + #ifdef CONFIG_GENERIC_TIME_VSYSCALL + extern void update_vsyscall(struct timespec *ts, struct clocksource *c); +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 1a52854..b1b0f68 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -647,8 +647,10 @@ static inline void netif_start_queue(struct net_device *dev) + static inline void netif_wake_queue(struct net_device *dev) + { + #ifdef CONFIG_NETPOLL_TRAP +- if (netpoll_trap()) ++ if (netpoll_trap()) { ++ clear_bit(__LINK_STATE_XOFF, &dev->state); + return; ++ } + #endif + if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state)) + __netif_schedule(dev); +@@ -656,10 +658,6 @@ static inline void netif_wake_queue(struct net_device *dev) + + static inline void netif_stop_queue(struct net_device *dev) + { +-#ifdef CONFIG_NETPOLL_TRAP +- if (netpoll_trap()) +- return; +-#endif + set_bit(__LINK_STATE_XOFF, &dev->state); + } + +diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h +index 4e6bbce..535e421 100644 +--- a/include/linux/netfilter/nf_conntrack_proto_gre.h ++++ b/include/linux/netfilter/nf_conntrack_proto_gre.h +@@ -87,24 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, + /* delete keymap entries */ + void nf_ct_gre_keymap_destroy(struct nf_conn *ct); + +-/* get pointer to gre key, if present */ +-static inline __be32 *gre_key(struct gre_hdr *greh) +-{ +- if (!greh->key) +- return NULL; +- if (greh->csum || greh->routing) +- return (__be32 *)(greh+sizeof(*greh)+4); +- return (__be32 *)(greh+sizeof(*greh)); +-} +- +-/* get pointer ot gre csum, if present */ +-static inline __sum16 *gre_csum(struct gre_hdr *greh) +-{ +- if (!greh->csum) +- return NULL; +- return (__sum16 *)(greh+sizeof(*greh)); +-} +- + extern void nf_ct_gre_keymap_flush(void); + extern void nf_nat_need_gre(void); + +diff --git a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h +index e371e0f..d0f36f5 100644 +--- a/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h ++++ b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h +@@ -90,25 +90,6 @@ int ip_ct_gre_keymap_add(struct ip_conntrack *ct, + /* delete keymap entries */ + void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct); + +- +-/* get pointer to gre key, if present */ +-static inline __be32 *gre_key(struct gre_hdr *greh) +-{ +- if (!greh->key) +- return NULL; +- if (greh->csum || greh->routing) +- return (__be32 *) (greh+sizeof(*greh)+4); +- return (__be32 *) (greh+sizeof(*greh)); +-} +- +-/* get pointer ot gre csum, if present */ +-static inline __sum16 *gre_csum(struct gre_hdr *greh) +-{ +- if (!greh->csum) +- return NULL; +- return (__sum16 *) (greh+sizeof(*greh)); +-} +- + #endif /* __KERNEL__ */ + + #endif /* _CONNTRACK_PROTO_GRE_H */ +diff --git a/kernel/cpuset.c b/kernel/cpuset.c +index f382b0f..9e45dd1 100644 +--- a/kernel/cpuset.c ++++ b/kernel/cpuset.c +@@ -1751,12 +1751,7 @@ static ssize_t cpuset_tasks_read(struct file *file, char __user *buf, + { + struct ctr_struct *ctr = file->private_data; + +- if (*ppos + nbytes > ctr->bufsz) +- nbytes = ctr->bufsz - *ppos; +- if (copy_to_user(buf, ctr->buf + *ppos, nbytes)) +- return -EFAULT; +- *ppos += nbytes; +- return nbytes; ++ return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz); + } + + static int cpuset_tasks_release(struct inode *unused_inode, struct file *file) +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index fe5c7db..5baee91 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -74,6 +74,8 @@ static struct clocksource *watchdog; + static struct timer_list watchdog_timer; + static DEFINE_SPINLOCK(watchdog_lock); + static cycle_t watchdog_last; ++static int watchdog_resumed; ++ + /* + * Interval: 0.5sec Treshold: 0.0625s + */ +@@ -98,15 +100,26 @@ static void clocksource_watchdog(unsigned long data) + struct clocksource *cs, *tmp; + cycle_t csnow, wdnow; + int64_t wd_nsec, cs_nsec; ++ int resumed; + + spin_lock(&watchdog_lock); + ++ resumed = watchdog_resumed; ++ if (unlikely(resumed)) ++ watchdog_resumed = 0; ++ + wdnow = watchdog->read(); + wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask); + watchdog_last = wdnow; + + list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) { + csnow = cs->read(); ++ ++ if (unlikely(resumed)) { ++ cs->wd_last = csnow; ++ continue; ++ } ++ + /* Initialized ? */ + if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) { + if ((cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) && +@@ -136,6 +149,13 @@ static void clocksource_watchdog(unsigned long data) + } + spin_unlock(&watchdog_lock); + } ++static void clocksource_resume_watchdog(void) ++{ ++ spin_lock(&watchdog_lock); ++ watchdog_resumed = 1; ++ spin_unlock(&watchdog_lock); ++} ++ + static void clocksource_check_watchdog(struct clocksource *cs) + { + struct clocksource *cse; +@@ -182,9 +202,34 @@ static void clocksource_check_watchdog(struct clocksource *cs) + if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) + cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES; + } ++ ++static inline void clocksource_resume_watchdog(void) { } + #endif + + /** ++ * clocksource_resume - resume the clocksource(s) ++ */ ++void clocksource_resume(void) ++{ ++ struct list_head *tmp; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&clocksource_lock, flags); ++ ++ list_for_each(tmp, &clocksource_list) { ++ struct clocksource *cs; ++ ++ cs = list_entry(tmp, struct clocksource, list); ++ if (cs->resume) ++ cs->resume(); ++ } ++ ++ clocksource_resume_watchdog(); ++ ++ spin_unlock_irqrestore(&clocksource_lock, flags); ++} ++ ++/** + * clocksource_get_next - Returns the selected clocksource + * + */ +diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c +index bfda3f7..a96ec9a 100644 +--- a/kernel/time/tick-common.c ++++ b/kernel/time/tick-common.c +@@ -31,7 +31,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device); + */ + ktime_t tick_next_period; + ktime_t tick_period; +-static int tick_do_timer_cpu = -1; ++int tick_do_timer_cpu __read_mostly = -1; + DEFINE_SPINLOCK(tick_device_lock); + + /* +@@ -295,6 +295,12 @@ static void tick_shutdown(unsigned int *cpup) + clockevents_exchange_device(dev, NULL); + td->evtdev = NULL; + } ++ /* Transfer the do_timer job away from this cpu */ ++ if (*cpup == tick_do_timer_cpu) { ++ int cpu = first_cpu(cpu_online_map); ++ ++ tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1; ++ } + spin_unlock_irqrestore(&tick_device_lock, flags); + } + +diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h +index c9d203b..bb13f27 100644 +--- a/kernel/time/tick-internal.h ++++ b/kernel/time/tick-internal.h +@@ -5,6 +5,7 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device); + extern spinlock_t tick_device_lock; + extern ktime_t tick_next_period; + extern ktime_t tick_period; ++extern int tick_do_timer_cpu __read_mostly; + + extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); + extern void tick_handle_periodic(struct clock_event_device *dev); +diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c +index 51556b9..f4fc867 100644 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -221,6 +221,18 @@ void tick_nohz_stop_sched_tick(void) + ts->tick_stopped = 1; + ts->idle_jiffies = last_jiffies; + } ++ ++ /* ++ * If this cpu is the one which updates jiffies, then ++ * give up the assignment and let it be taken by the ++ * cpu which runs the tick timer next, which might be ++ * this cpu as well. If we don't drop this here the ++ * jiffies might be stale and do_timer() never ++ * invoked. ++ */ ++ if (cpu == tick_do_timer_cpu) ++ tick_do_timer_cpu = -1; ++ + /* + * calculate the expiry time for the next timer wheel + * timer +@@ -338,12 +350,24 @@ static void tick_nohz_handler(struct clock_event_device *dev) + { + struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); + struct pt_regs *regs = get_irq_regs(); ++ int cpu = smp_processor_id(); + ktime_t now = ktime_get(); + + dev->next_event.tv64 = KTIME_MAX; + ++ /* ++ * Check if the do_timer duty was dropped. We don't care about ++ * concurrency: This happens only when the cpu in charge went ++ * into a long sleep. If two cpus happen to assign themself to ++ * this duty, then the jiffies update is still serialized by ++ * xtime_lock. ++ */ ++ if (unlikely(tick_do_timer_cpu == -1)) ++ tick_do_timer_cpu = cpu; ++ + /* Check, if the jiffies need an update */ +- tick_do_update_jiffies64(now); ++ if (tick_do_timer_cpu == cpu) ++ tick_do_update_jiffies64(now); + + /* + * When we are idle and the tick is stopped, we have to touch +@@ -431,9 +455,23 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) + struct hrtimer_cpu_base *base = timer->base->cpu_base; + struct pt_regs *regs = get_irq_regs(); + ktime_t now = ktime_get(); ++ int cpu = smp_processor_id(); ++ ++#ifdef CONFIG_NO_HZ ++ /* ++ * Check if the do_timer duty was dropped. We don't care about ++ * concurrency: This happens only when the cpu in charge went ++ * into a long sleep. If two cpus happen to assign themself to ++ * this duty, then the jiffies update is still serialized by ++ * xtime_lock. ++ */ ++ if (unlikely(tick_do_timer_cpu == -1)) ++ tick_do_timer_cpu = cpu; ++#endif + + /* Check, if the jiffies need an update */ +- tick_do_update_jiffies64(now); ++ if (tick_do_timer_cpu == cpu) ++ tick_do_update_jiffies64(now); + + /* + * Do not call, when we are not in irq context and have +diff --git a/kernel/timer.c b/kernel/timer.c +index dd6c2c1..e045774 100644 +--- a/kernel/timer.c ++++ b/kernel/timer.c +@@ -1903,6 +1903,8 @@ unregister_time_interpolator(struct time_interpolator *ti) + prev = &curr->next; + } + ++ clocksource_resume(); ++ + write_seqlock_irqsave(&xtime_lock, flags); + if (ti == time_interpolator) { + /* we lost the best time-interpolator: */ +diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c +index fceb97c..7e1e311 100644 +--- a/lib/zlib_inflate/inflate.c ++++ b/lib/zlib_inflate/inflate.c +@@ -743,12 +743,14 @@ int zlib_inflate(z_streamp strm, int flush) + + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); +- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) +- ret = Z_BUF_ERROR; + + if (flush == Z_PACKET_FLUSH && ret == Z_OK && +- (strm->avail_out != 0 || strm->avail_in == 0)) ++ strm->avail_out != 0 && strm->avail_in == 0) + return zlib_inflateSyncPacket(strm); ++ ++ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ++ ret = Z_BUF_ERROR; ++ + return ret; + } + +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 36db012..88e708b 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -140,6 +140,8 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, + return page; + + fail: ++ if (vma->vm_flags & VM_MAYSHARE) ++ resv_huge_pages++; + spin_unlock(&hugetlb_lock); + return NULL; + } +diff --git a/mm/oom_kill.c b/mm/oom_kill.c +index 3791edf..b3a3dd6 100644 +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -397,6 +397,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) + struct task_struct *p; + unsigned long points = 0; + unsigned long freed = 0; ++ int constraint; + + blocking_notifier_call_chain(&oom_notify_list, 0, &freed); + if (freed > 0) +@@ -411,14 +412,15 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) + show_mem(); + } + +- cpuset_lock(); +- read_lock(&tasklist_lock); +- + /* + * Check if there were limitations on the allocation (only relevant for + * NUMA) that may require different handling. + */ +- switch (constrained_alloc(zonelist, gfp_mask)) { ++ constraint = constrained_alloc(zonelist, gfp_mask); ++ cpuset_lock(); ++ read_lock(&tasklist_lock); ++ ++ switch (constraint) { + case CONSTRAINT_MEMORY_POLICY: + oom_kill_process(current, points, + "No available memory (MPOL_BIND)"); +diff --git a/mm/slob.c b/mm/slob.c +index 5adc29c..c683d35 100644 +--- a/mm/slob.c ++++ b/mm/slob.c +@@ -150,15 +150,6 @@ static void slob_free(void *block, int size) + spin_unlock_irqrestore(&slob_lock, flags); + } + +-static int FASTCALL(find_order(int size)); +-static int fastcall find_order(int size) +-{ +- int order = 0; +- for ( ; size > 4096 ; size >>=1) +- order++; +- return order; +-} +- + void *__kmalloc(size_t size, gfp_t gfp) + { + slob_t *m; +@@ -174,7 +165,7 @@ void *__kmalloc(size_t size, gfp_t gfp) + if (!bb) + return 0; + +- bb->order = find_order(size); ++ bb->order = get_order(size); + bb->pages = (void *)__get_free_pages(gfp, bb->order); + + if (bb->pages) { +@@ -284,7 +275,7 @@ void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags) + if (c->size < PAGE_SIZE) + b = slob_alloc(c->size, flags, c->align); + else +- b = (void *)__get_free_pages(flags, find_order(c->size)); ++ b = (void *)__get_free_pages(flags, get_order(c->size)); + + if (c->ctor) + c->ctor(b, c, SLAB_CTOR_CONSTRUCTOR); +@@ -311,7 +302,7 @@ void kmem_cache_free(struct kmem_cache *c, void *b) + if (c->size < PAGE_SIZE) + slob_free(b, c->size); + else +- free_pages((unsigned long)b, find_order(c->size)); ++ free_pages((unsigned long)b, get_order(c->size)); + } + EXPORT_SYMBOL(kmem_cache_free); + +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index cac06c4..444a56b 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -777,6 +777,10 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) + .tos = frn->fl_tos, + .scope = frn->fl_scope } } }; + ++#ifdef CONFIG_IP_MULTIPLE_TABLES ++ res.r = NULL; ++#endif ++ + frn->err = -ENOENT; + if (tb) { + local_bh_disable(); +diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c +index 23b99ae..75bd597 100644 +--- a/net/ipv4/netfilter/ip_conntrack_core.c ++++ b/net/ipv4/netfilter/ip_conntrack_core.c +@@ -302,7 +302,6 @@ destroy_conntrack(struct nf_conntrack *nfct) + { + struct ip_conntrack *ct = (struct ip_conntrack *)nfct; + struct ip_conntrack_protocol *proto; +- struct ip_conntrack_helper *helper; + typeof(ip_conntrack_destroyed) destroyed; + + DEBUGP("destroy_conntrack(%p)\n", ct); +@@ -312,10 +311,6 @@ destroy_conntrack(struct nf_conntrack *nfct) + ip_conntrack_event(IPCT_DESTROY, ct); + set_bit(IPS_DYING_BIT, &ct->status); + +- helper = ct->helper; +- if (helper && helper->destroy) +- helper->destroy(ct); +- + /* To make sure we don't get any weird locking issues here: + * destroy_conntrack() MUST NOT be called with a write lock + * to ip_conntrack_lock!!! -HW */ +@@ -356,6 +351,11 @@ destroy_conntrack(struct nf_conntrack *nfct) + static void death_by_timeout(unsigned long ul_conntrack) + { + struct ip_conntrack *ct = (void *)ul_conntrack; ++ struct ip_conntrack_helper *helper; ++ ++ helper = ct->helper; ++ if (helper && helper->destroy) ++ helper->destroy(ct); + + write_lock_bh(&ip_conntrack_lock); + /* Inside lock so preempt is disabled on module removal path. +diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +index e694299..b86479a 100644 +--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c ++++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +@@ -460,7 +460,8 @@ static int sctp_new(struct ip_conntrack *conntrack, + SCTP_CONNTRACK_NONE, sch->type); + + /* Invalid: delete conntrack */ +- if (newconntrack == SCTP_CONNTRACK_MAX) { ++ if (newconntrack == SCTP_CONNTRACK_NONE || ++ newconntrack == SCTP_CONNTRACK_MAX) { + DEBUGP("ip_conntrack_sctp: invalid new deleting.\n"); + return 0; + } +diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c +index 9581020..e3146a3 100644 +--- a/net/ipv4/netfilter/ip_nat_proto_gre.c ++++ b/net/ipv4/netfilter/ip_nat_proto_gre.c +@@ -70,6 +70,11 @@ gre_unique_tuple(struct ip_conntrack_tuple *tuple, + __be16 *keyptr; + unsigned int min, i, range_size; + ++ /* If there is no master conntrack we are not PPTP, ++ do not change tuples */ ++ if (!conntrack->master) ++ return 0; ++ + if (maniptype == IP_NAT_MANIP_SRC) + keyptr = &tuple->src.u.gre.key; + else +@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, + if (maniptype == IP_NAT_MANIP_DST) { + /* key manipulation is always dest */ + switch (greh->version) { +- case 0: +- if (!greh->key) { +- DEBUGP("can't nat GRE w/o key\n"); +- break; +- } +- if (greh->csum) { +- /* FIXME: Never tested this code... */ +- nf_proto_csum_replace4(gre_csum(greh), *pskb, +- *(gre_key(greh)), +- tuple->dst.u.gre.key, 0); +- } +- *(gre_key(greh)) = tuple->dst.u.gre.key; ++ case GRE_VERSION_1701: ++ /* We do not currently NAT any GREv0 packets. ++ * Try to behave like "ip_nat_proto_unknown" */ + break; + case GRE_VERSION_PPTP: + DEBUGP("call_id -> 0x%04x\n", +diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c +index e5a34c1..ca3ff84 100644 +--- a/net/ipv4/netfilter/nf_nat_proto_gre.c ++++ b/net/ipv4/netfilter/nf_nat_proto_gre.c +@@ -72,6 +72,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, + __be16 *keyptr; + unsigned int min, i, range_size; + ++ /* If there is no master conntrack we are not PPTP, ++ do not change tuples */ ++ if (!conntrack->master) ++ return 0; ++ + if (maniptype == IP_NAT_MANIP_SRC) + keyptr = &tuple->src.u.gre.key; + else +@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff, + if (maniptype != IP_NAT_MANIP_DST) + return 1; + switch (greh->version) { +- case 0: +- if (!greh->key) { +- DEBUGP("can't nat GRE w/o key\n"); +- break; +- } +- if (greh->csum) { +- /* FIXME: Never tested this code... */ +- nf_proto_csum_replace4(gre_csum(greh), *pskb, +- *(gre_key(greh)), +- tuple->dst.u.gre.key, 0); +- } +- *(gre_key(greh)) = tuple->dst.u.gre.key; ++ case GRE_VERSION_1701: ++ /* We do not currently NAT any GREv0 packets. ++ * Try to behave like "nf_nat_proto_unknown" */ + break; + case GRE_VERSION_PPTP: + DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 3834b10..824c6b9 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1759,8 +1759,7 @@ int tcp_disconnect(struct sock *sk, int flags) + tcp_clear_retrans(tp); + inet_csk_delack_init(sk); + sk->sk_send_head = NULL; +- tp->rx_opt.saw_tstamp = 0; +- tcp_sack_reset(&tp->rx_opt); ++ memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); + __sk_dst_reset(sk); + + BUG_TRAP(!inet->num || icsk->icsk_bind_hash); +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 452a82c..a541137 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2281,8 +2281,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, + break; + + case NETDEV_CHANGENAME: +-#ifdef CONFIG_SYSCTL + if (idev) { ++ snmp6_unregister_dev(idev); ++#ifdef CONFIG_SYSCTL + addrconf_sysctl_unregister(&idev->cnf); + neigh_sysctl_unregister(idev->nd_parms); + neigh_sysctl_register(dev, idev->nd_parms, +@@ -2290,8 +2291,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, + &ndisc_ifinfo_sysctl_change, + NULL); + addrconf_sysctl_register(idev, &idev->cnf); +- } + #endif ++ snmp6_register_dev(idev); ++ } + break; + }; + +@@ -4060,6 +4062,10 @@ int __init addrconf_init(void) + return err; + + ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); ++#ifdef CONFIG_IPV6_MULTIPLE_TABLES ++ ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev); ++ ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev); ++#endif + + register_netdevice_notifier(&ipv6_dev_notf); + +diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c +index fb39604..794b930 100644 +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -396,6 +396,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) + + switch (hdr->type) { + #ifdef CONFIG_IPV6_MIP6 ++ case IPV6_SRCRT_TYPE_2: + break; + #endif + case IPV6_SRCRT_TYPE_0: +@@ -651,6 +652,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr); + Hop-by-hop options. + **********************************/ + ++/* ++ * Note: we cannot rely on skb->dst before we assign it in ip6_route_input(). ++ */ ++static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb) ++{ ++ return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev); ++} ++ + /* Router Alert as of RFC 2711 */ + + static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) +@@ -677,25 +686,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) + if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { + LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", + skb->nh.raw[optoff+1]); +- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), ++ IP6_INC_STATS_BH(ipv6_skb_idev(skb), + IPSTATS_MIB_INHDRERRORS); + goto drop; + } + + pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2)); + if (pkt_len <= IPV6_MAXPLEN) { +- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); ++ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); + icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); + return 0; + } + if (skb->nh.ipv6h->payload_len) { +- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); ++ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); + icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); + return 0; + } + + if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { +- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS); ++ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS); + goto drop; + } + +diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c +index 61e7a6c..1b34ee5 100644 +--- a/net/ipv6/ip6_input.c ++++ b/net/ipv6/ip6_input.c +@@ -235,7 +235,7 @@ int ip6_mc_input(struct sk_buff *skb) + IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); + + hdr = skb->nh.ipv6h; +- deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || ++ deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || + ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); + + /* +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 3055169..9fa3ffb 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -449,10 +449,17 @@ int ip6_forward(struct sk_buff *skb) + */ + if (xrlim_allow(dst, 1*HZ)) + ndisc_send_redirect(skb, n, target); +- } else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK +- |IPV6_ADDR_LINKLOCAL)) { ++ } else { ++ int addrtype = ipv6_addr_type(&hdr->saddr); ++ + /* This check is security critical. */ +- goto error; ++ if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK)) ++ goto error; ++ if (addrtype & IPV6_ADDR_LINKLOCAL) { ++ icmpv6_send(skb, ICMPV6_DEST_UNREACH, ++ ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); ++ goto error; ++ } + } + + if (skb->len > dst_mtu(dst)) { +diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c +index fa3fb50..d57853d 100644 +--- a/net/ipv6/proc.c ++++ b/net/ipv6/proc.c +@@ -236,6 +236,7 @@ int snmp6_unregister_dev(struct inet6_dev *idev) + return -EINVAL; + remove_proc_entry(idev->stats.proc_dir_entry->name, + proc_net_devsnmp6); ++ idev->stats.proc_dir_entry = NULL; + return 0; + } + +diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c +index 93c4223..dff33cc 100644 +--- a/net/ipv6/xfrm6_tunnel.c ++++ b/net/ipv6/xfrm6_tunnel.c +@@ -261,7 +261,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb) + __be32 spi; + + spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); +- return xfrm6_rcv_spi(skb, spi); ++ return xfrm6_rcv_spi(skb, spi) > 0 ? : 0; + } + + static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index b3a70eb..ce28fdd 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -315,7 +315,6 @@ static void + destroy_conntrack(struct nf_conntrack *nfct) + { + struct nf_conn *ct = (struct nf_conn *)nfct; +- struct nf_conn_help *help = nfct_help(ct); + struct nf_conntrack_l3proto *l3proto; + struct nf_conntrack_l4proto *l4proto; + typeof(nf_conntrack_destroyed) destroyed; +@@ -327,9 +326,6 @@ destroy_conntrack(struct nf_conntrack *nfct) + nf_conntrack_event(IPCT_DESTROY, ct); + set_bit(IPS_DYING_BIT, &ct->status); + +- if (help && help->helper && help->helper->destroy) +- help->helper->destroy(ct); +- + /* To make sure we don't get any weird locking issues here: + * destroy_conntrack() MUST NOT be called with a write lock + * to nf_conntrack_lock!!! -HW */ +@@ -375,6 +371,10 @@ destroy_conntrack(struct nf_conntrack *nfct) + static void death_by_timeout(unsigned long ul_conntrack) + { + struct nf_conn *ct = (void *)ul_conntrack; ++ struct nf_conn_help *help = nfct_help(ct); ++ ++ if (help && help->helper && help->helper->destroy) ++ help->helper->destroy(ct); + + write_lock_bh(&nf_conntrack_lock); + /* Inside lock so preempt is disabled on module removal path. +diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c +index 3c80558..b53bc64 100644 +--- a/net/netfilter/nf_conntrack_proto_sctp.c ++++ b/net/netfilter/nf_conntrack_proto_sctp.c +@@ -469,7 +469,8 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb, + SCTP_CONNTRACK_NONE, sch->type); + + /* Invalid: delete conntrack */ +- if (newconntrack == SCTP_CONNTRACK_MAX) { ++ if (newconntrack == SCTP_CONNTRACK_NONE || ++ newconntrack == SCTP_CONNTRACK_MAX) { + DEBUGP("nf_conntrack_sctp: invalid new deleting.\n"); + return 0; + } +diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c +index de889f2..a86f36b 100644 +--- a/net/sched/sch_prio.c ++++ b/net/sched/sch_prio.c +@@ -74,7 +74,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) + band = res.classid; + } + band = TC_H_MIN(band) - 1; +- if (band > q->bands) ++ if (band >= q->bands) + return q->queues[q->prio2band[0]]; + + return q->queues[band]; +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index a1d026f..843c928 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -3847,7 +3847,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, + memcpy(&temp, &from->ipaddr, sizeof(temp)); + sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); + addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; +- if(space_left < addrlen) ++ if (space_left < addrlen) + return -ENOMEM; + if (copy_to_user(to, &temp, addrlen)) + return -EFAULT; +@@ -3936,8 +3936,9 @@ done: + /* Helper function that copies local addresses to user and returns the number + * of addresses copied. + */ +-static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs, +- void __user *to) ++static int sctp_copy_laddrs_old(struct sock *sk, __u16 port, ++ int max_addrs, void *to, ++ int *bytes_copied) + { + struct list_head *pos, *next; + struct sctp_sockaddr_entry *addr; +@@ -3954,10 +3955,10 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add + sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), + &temp); + addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; +- if (copy_to_user(to, &temp, addrlen)) +- return -EFAULT; ++ memcpy(to, &temp, addrlen); + + to += addrlen; ++ *bytes_copied += addrlen; + cnt ++; + if (cnt >= max_addrs) break; + } +@@ -3965,8 +3966,8 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add + return cnt; + } + +-static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, +- void __user **to, size_t space_left) ++static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, ++ size_t space_left, int *bytes_copied) + { + struct list_head *pos, *next; + struct sctp_sockaddr_entry *addr; +@@ -3983,14 +3984,14 @@ static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, + sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), + &temp); + addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; +- if(space_left<addrlen) ++ if (space_left < addrlen) + return -ENOMEM; +- if (copy_to_user(*to, &temp, addrlen)) +- return -EFAULT; ++ memcpy(to, &temp, addrlen); + +- *to += addrlen; ++ to += addrlen; + cnt ++; + space_left -= addrlen; ++ bytes_copied += addrlen; + } + + return cnt; +@@ -4014,6 +4015,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, + int addrlen; + rwlock_t *addr_lock; + int err = 0; ++ void *addrs; ++ void *buf; ++ int bytes_copied = 0; + + if (len != sizeof(struct sctp_getaddrs_old)) + return -EINVAL; +@@ -4041,6 +4045,15 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, + + to = getaddrs.addrs; + ++ /* Allocate space for a local instance of packed array to hold all ++ * the data. We store addresses here first and then put write them ++ * to the user in one shot. ++ */ ++ addrs = kmalloc(sizeof(union sctp_addr) * getaddrs.addr_num, ++ GFP_KERNEL); ++ if (!addrs) ++ return -ENOMEM; ++ + sctp_read_lock(addr_lock); + + /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid +@@ -4050,38 +4063,42 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, + addr = list_entry(bp->address_list.next, + struct sctp_sockaddr_entry, list); + if (sctp_is_any(&addr->a)) { +- cnt = sctp_copy_laddrs_to_user_old(sk, bp->port, +- getaddrs.addr_num, +- to); +- if (cnt < 0) { +- err = cnt; +- goto unlock; +- } ++ cnt = sctp_copy_laddrs_old(sk, bp->port, ++ getaddrs.addr_num, ++ addrs, &bytes_copied); + goto copy_getaddrs; + } + } + ++ buf = addrs; + list_for_each(pos, &bp->address_list) { + addr = list_entry(pos, struct sctp_sockaddr_entry, list); + memcpy(&temp, &addr->a, sizeof(temp)); + sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); + addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; +- if (copy_to_user(to, &temp, addrlen)) { +- err = -EFAULT; +- goto unlock; +- } +- to += addrlen; ++ memcpy(buf, &temp, addrlen); ++ buf += addrlen; ++ bytes_copied += addrlen; + cnt ++; + if (cnt >= getaddrs.addr_num) break; + } + + copy_getaddrs: ++ sctp_read_unlock(addr_lock); ++ ++ /* copy the entire address list into the user provided space */ ++ if (copy_to_user(to, addrs, bytes_copied)) { ++ err = -EFAULT; ++ goto error; ++ } ++ ++ /* copy the leading structure back to user */ + getaddrs.addr_num = cnt; + if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) + err = -EFAULT; + +-unlock: +- sctp_read_unlock(addr_lock); ++error: ++ kfree(addrs); + return err; + } + +@@ -4101,7 +4118,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, + rwlock_t *addr_lock; + int err = 0; + size_t space_left; +- int bytes_copied; ++ int bytes_copied = 0; ++ void *addrs; ++ void *buf; + + if (len <= sizeof(struct sctp_getaddrs)) + return -EINVAL; +@@ -4129,6 +4148,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, + to = optval + offsetof(struct sctp_getaddrs,addrs); + space_left = len - sizeof(struct sctp_getaddrs) - + offsetof(struct sctp_getaddrs,addrs); ++ addrs = kmalloc(space_left, GFP_KERNEL); ++ if (!addrs) ++ return -ENOMEM; + + sctp_read_lock(addr_lock); + +@@ -4139,41 +4161,47 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, + addr = list_entry(bp->address_list.next, + struct sctp_sockaddr_entry, list); + if (sctp_is_any(&addr->a)) { +- cnt = sctp_copy_laddrs_to_user(sk, bp->port, +- &to, space_left); ++ cnt = sctp_copy_laddrs(sk, bp->port, addrs, ++ space_left, &bytes_copied); + if (cnt < 0) { + err = cnt; +- goto unlock; ++ goto error; + } + goto copy_getaddrs; + } + } + ++ buf = addrs; + list_for_each(pos, &bp->address_list) { + addr = list_entry(pos, struct sctp_sockaddr_entry, list); + memcpy(&temp, &addr->a, sizeof(temp)); + sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); + addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; +- if(space_left < addrlen) +- return -ENOMEM; /*fixme: right error?*/ +- if (copy_to_user(to, &temp, addrlen)) { +- err = -EFAULT; +- goto unlock; ++ if (space_left < addrlen) { ++ err = -ENOMEM; /*fixme: right error?*/ ++ goto error; + } +- to += addrlen; ++ memcpy(buf, &temp, addrlen); ++ buf += addrlen; ++ bytes_copied += addrlen; + cnt ++; + space_left -= addrlen; + } + + copy_getaddrs: ++ sctp_read_unlock(addr_lock); ++ ++ if (copy_to_user(to, addrs, bytes_copied)) { ++ err = -EFAULT; ++ goto error; ++ } + if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) + return -EFAULT; +- bytes_copied = ((char __user *)to) - optval; + if (put_user(bytes_copied, optlen)) + return -EFAULT; + +-unlock: +- sctp_read_unlock(addr_lock); ++error: ++ kfree(addrs); + return err; + } + +@@ -4961,7 +4989,12 @@ int sctp_inet_listen(struct socket *sock, int backlog) + /* Allocate HMAC for generating cookie. */ + if (sctp_hmac_alg) { + tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); +- if (!tfm) { ++ if (IS_ERR(tfm)) { ++ if (net_ratelimit()) { ++ printk(KERN_INFO ++ "SCTP: failed to load transform for %s: %ld\n", ++ sctp_hmac_alg, PTR_ERR(tfm)); ++ } + err = -ENOSYS; + goto out; + } +diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c +index db298b5..c678f5f 100644 +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -1196,13 +1196,7 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp) + if (xdr_buf_subsegment(resbuf, &integ_buf, integ_offset, + integ_len)) + BUG(); +- if (resbuf->page_len == 0 +- && resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE +- < PAGE_SIZE) { +- BUG_ON(resbuf->tail[0].iov_len); +- /* Use head for everything */ +- resv = &resbuf->head[0]; +- } else if (resbuf->tail[0].iov_base == NULL) { ++ if (resbuf->tail[0].iov_base == NULL) { + if (resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE > PAGE_SIZE) + goto out_err; + resbuf->tail[0].iov_base = resbuf->head[0].iov_base +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index 785c3e3..ba89293 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -782,6 +782,10 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, + struct hlist_head *chain; + struct hlist_node *entry; + ++ *err = -ENOENT; ++ if (xfrm_policy_id2dir(id) != dir) ++ return NULL; ++ + *err = 0; + write_lock_bh(&xfrm_policy_lock); + chain = xfrm_policy_byidx + idx_hash(id); +diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c +index 6bc7e7c..8912c0f 100644 +--- a/scripts/basic/fixdep.c ++++ b/scripts/basic/fixdep.c +@@ -249,6 +249,8 @@ void parse_config_file(char *map, size_t len) + found: + if (!memcmp(q - 7, "_MODULE", 7)) + q -= 7; ++ if( (q-p-7) < 0 ) ++ continue; + use_config(p+7, q-p-7); + } + } +diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c +index c94291b..a6f8992 100644 +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -1751,6 +1751,7 @@ static int stac92xx_resume(struct hda_codec *codec) + + stac92xx_init(codec); + stac92xx_set_config_regs(codec); ++ snd_hda_resume_ctls(codec, spec->mixer); + for (i = 0; i < spec->num_mixers; i++) + snd_hda_resume_ctls(codec, spec->mixers[i]); + if (spec->multiout.dig_out_nid) |