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 #include #include +#include #include #include @@ -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 * 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@adaptec.com) + * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@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//rp_filter + echo 1 > /proc/sys/net/ipv4/conf//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 */