[kernel] r9287 - in dists/sid/linux-2.6/debian: . patches/bugfix patches/series
Maximilian Attems
maks at alioth.debian.org
Fri Aug 10 06:41:21 UTC 2007
Author: maks
Date: Fri Aug 10 06:41:20 2007
New Revision: 9287
Log:
add huge 2.6.22.2
Added:
dists/sid/linux-2.6/debian/patches/bugfix/2.6.22.2
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/4
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog (original)
+++ dists/sid/linux-2.6/debian/changelog Fri Aug 10 06:41:20 2007
@@ -12,7 +12,93 @@
[ Emanuele Rocca ]
* [sparc] Add patch to fix PCI config space accesses on sun4u.
- -- dann frazier <dannf at debian.org> Mon, 30 Jul 2007 11:23:31 -0600
+ [ maximilian attems ]
+ * Add stable release 2.6.22.2:
+ - usb-serial: Fix edgeport regression on non-EPiC devices
+ - Missing header include in ipt_iprange.h
+ - drivers/video/macmodes.c:mac_find_mode() mustn't be __devinit
+ - Fix ipv6 tunnel endianness bug.
+ - aacraid: fix security hole
+ - USB: cdc-acm: fix sysfs attribute registration bug
+ - USB: fix warning caused by autosuspend counter going negative
+ - Fix sparc32 memset()
+ - Fix leak on /proc/lockdep_stats
+ - Fix leaks on /proc/{*/sched, sched_debug, timer_list, timer_stats}
+ - futex: pass nr_wake2 to futex_wake_op
+ - md: handle writes to broken raid10 arrays gracefully
+ - forcedeth bug fix: cicada phy
+ - forcedeth bug fix: vitesse phy
+ - forcedeth bug fix: realtek phy
+ - ACPI: dock: fix opps after dock driver fails to initialize
+ - pcmcia: give socket time to power down
+ - drm/i915: Fix i965 secured batchbuffer usage (CVE-2007-3851)
+ - Fix console write locking in sparc drivers.
+ - Sparc64 bootup assembler bug
+ - IPV6: /proc/net/anycast6 unbalanced inet6_dev refcnt
+ - make timerfd return a u64 and fix the __put_user
+ - Fix error queue socket lookup in ipv6
+ - Input: lifebook - fix an oops on Panasonic CF-18
+ - readahead: MIN_RA_PAGES/MAX_RA_PAGES macros
+ - V4L: Add check for valid control ID to v4l2_ctrl_next
+ - V4L: ivtv: fix broken VBI output support
+ - V4L: ivtv: fix DMA timeout when capturing VBI + another stream
+ - V4L: ivtv: Add locking to ensure stream setup is atomic
+ - V4L: wm8775/wm8739: Fix memory leak when unloading module
+ - do not limit locked memory when RLIMIT_MEMLOCK is RLIM_INFINITY
+ - Include serial_reg.h with userspace headers (closes: #433755)
+ - TCP FRTO retransmit bug fix
+ - Fix rfkill IRQ flags.
+ - nfsd: fix possible read-ahead cache and export table corruption
+ - nfsd: fix possible oops on re-insertion of rpcsec_gss modules
+ - jbd commit: fix transaction dropping
+ - jbd2 commit: fix transaction dropping
+ - softmac: Fix ESSID problem
+ - uml: limit request size on COWed devices
+ - UML: exports for hostfs
+ - splice: fix double page unlock
+ - cfq-iosched: fix async queue behaviour
+ - cr_backlight_probe() allocates too little storage for struct cr_panel
+ - sx: switch subven and subid values
+ - hugetlb: fix race in alloc_fresh_huge_page()
+ - KVM: SVM: Reliably detect if SVM was disabled by BIOS
+ - dm io: fix another panic on large request
+ - md: raid10: fix use-after-free of bio
+ - fs: 9p/conv.c error path fix
+ - Fix sparc32 udelay() rounding errors.
+ - sony-laptop: fix bug in event handling
+ - eCryptfs: ecryptfs_setattr() bugfix
+ - Hangup TTY before releasing rfcomm_dev
+ - dm io: fix panic on large request
+ - dm raid1: fix status
+ - dm snapshot: permit invalid activation
+ - "ext4_ext_put_in_cache" uses __u32 to receive physical block number
+ - destroy_workqueue() can livelock
+ - USB: fix for ftdi_sio quirk handling
+ - Fix TC deadlock.
+ - Fix IPCOMP crashes.
+ - gen estimator timer unload race
+ - Netfilter: Fix logging regression
+ - Fix user struct leakage with locked IPC shem segment
+ - Fix reported task file values in sense data
+ - gen estimator deadlock fix
+ - Netpoll leak
+ - dm: disable barriers
+ - firewire: fw-sbp2: set correct maximum payload (fixes CardBus adapters)
+ - fw-ohci: fix "scheduling while atomic"
+ - firewire: fix memory leak of fw_request instances
+ - ieee1394: revert "sbp2: enforce 32bit DMA mapping"
+ - libata: add FUJITSU MHV2080BH to NCQ blacklist
+ - i386: HPET, check if the counter works
+ - CPU online file permission
+ - acpi-cpufreq: Proper ReadModifyWrite of PERF_CTL MSR
+ - Keep rfcomm_dev on the list until it is freed
+ - SCTP scope_id handling fix
+ - Fix ipv6 link down handling.
+ - Fix TCP IPV6 MD5 bug.
+ - sysfs: release mutex when kmalloc() failed in sysfs_open_file().
+ - nf_conntrack: don't track locally generated special ICMP error
+
+ -- maximilian attems <maks at debian.org> Fri, 10 Aug 2007 08:30:30 +0200
linux-2.6 (2.6.22-3) unstable; urgency=low
Added: dists/sid/linux-2.6/debian/patches/bugfix/2.6.22.2
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/bugfix/2.6.22.2 Fri Aug 10 06:41:20 2007
@@ -0,0 +1,2875 @@
+diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+index 10baa35..18c8b67 100644
+--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
++++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+@@ -167,11 +167,13 @@ static void do_drv_read(struct drv_cmd *cmd)
+
+ static void do_drv_write(struct drv_cmd *cmd)
+ {
+- u32 h = 0;
++ u32 lo, hi;
+
+ switch (cmd->type) {
+ case SYSTEM_INTEL_MSR_CAPABLE:
+- wrmsr(cmd->addr.msr.reg, cmd->val, h);
++ rdmsr(cmd->addr.msr.reg, lo, hi);
++ lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE);
++ wrmsr(cmd->addr.msr.reg, lo, hi);
+ break;
+ case SYSTEM_IO_CAPABLE:
+ acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
+@@ -372,7 +374,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
+ struct cpufreq_freqs freqs;
+ cpumask_t online_policy_cpus;
+ struct drv_cmd cmd;
+- unsigned int msr;
+ unsigned int next_state = 0; /* Index into freq_table */
+ unsigned int next_perf_state = 0; /* Index into perf table */
+ unsigned int i;
+@@ -417,11 +418,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
+ case SYSTEM_INTEL_MSR_CAPABLE:
+ cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
+ cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
+- msr =
+- (u32) perf->states[next_perf_state].
+- control & INTEL_MSR_RANGE;
+- cmd.val = get_cur_val(online_policy_cpus);
+- cmd.val = (cmd.val & ~INTEL_MSR_RANGE) | msr;
++ cmd.val = (u32) perf->states[next_perf_state].control;
+ break;
+ case SYSTEM_IO_CAPABLE:
+ cmd.type = SYSTEM_IO_CAPABLE;
+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/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
+index 831f540..eac3838 100644
+--- a/arch/sparc/kernel/entry.S
++++ b/arch/sparc/kernel/entry.S
+@@ -1749,8 +1749,8 @@ fpload:
+ __ndelay:
+ save %sp, -STACKFRAME_SZ, %sp
+ mov %i0, %o0
+- call .umul
+- mov 0x1ad, %o1 ! 2**32 / (1 000 000 000 / HZ)
++ call .umul ! round multiplier up so large ns ok
++ mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ)
+ call .umul
+ mov %i1, %o1 ! udelay_val
+ ba delay_continue
+@@ -1760,11 +1760,17 @@ __ndelay:
+ __udelay:
+ save %sp, -STACKFRAME_SZ, %sp
+ mov %i0, %o0
+- sethi %hi(0x10c6), %o1
++ sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok
+ call .umul
+- or %o1, %lo(0x10c6), %o1 ! 2**32 / 1 000 000
++ or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000
+ call .umul
+ mov %i1, %o1 ! udelay_val
++ sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32,
++ or %g0, %lo(0x028f4b62), %l0
++ addcc %o0, %l0, %o0 ! 2**32 * 0.009 999
++ bcs,a 3f
++ add %o1, 0x01, %o1
++3:
+ call .umul
+ mov HZ, %o0 ! >>32 earlier for wider range
+
+diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S
+index a65eba4..1c37ea8 100644
+--- a/arch/sparc/lib/memset.S
++++ b/arch/sparc/lib/memset.S
+@@ -162,7 +162,7 @@ __bzero:
+ 8:
+ add %o0, 1, %o0
+ subcc %o1, 1, %o1
+- bne,a 8b
++ bne 8b
+ EX(stb %g3, [%o0 - 1], add %o1, 1)
+ 0:
+ retl
+diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
+index 7725952..35feacb 100644
+--- a/arch/sparc64/kernel/head.S
++++ b/arch/sparc64/kernel/head.S
+@@ -458,7 +458,6 @@ tlb_fixup_done:
+ or %g6, %lo(init_thread_union), %g6
+ ldx [%g6 + TI_TASK], %g4
+ mov %sp, %l6
+- mov %o4, %l7
+
+ wr %g0, ASI_P, %asi
+ mov 1, %g1
+diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
+index 2e09f16..c6acc1a 100644
+--- a/arch/um/drivers/ubd_kern.c
++++ b/arch/um/drivers/ubd_kern.c
+@@ -712,6 +712,8 @@ static int ubd_add(int n, char **error_out)
+ ubd_dev->queue->queuedata = ubd_dev;
+
+ blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
++ if(ubd_dev->cow.file != NULL)
++ blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
+ err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
+ if(err){
+ *error_out = "Failed to register device";
+diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
+index 3f33165..419b2d5 100644
+--- a/arch/um/os-Linux/user_syms.c
++++ b/arch/um/os-Linux/user_syms.c
+@@ -5,7 +5,8 @@
+ * so I *must* declare good prototypes for them and then EXPORT them.
+ * The kernel code uses the macro defined by include/linux/string.h,
+ * so I undef macros; the userspace code does not include that and I
+- * add an EXPORT for the glibc one.*/
++ * add an EXPORT for the glibc one.
++ */
+
+ #undef strlen
+ #undef strstr
+@@ -61,12 +62,18 @@ EXPORT_SYMBOL_PROTO(dup2);
+ EXPORT_SYMBOL_PROTO(__xstat);
+ EXPORT_SYMBOL_PROTO(__lxstat);
+ EXPORT_SYMBOL_PROTO(__lxstat64);
++EXPORT_SYMBOL_PROTO(__fxstat64);
+ EXPORT_SYMBOL_PROTO(lseek);
+ EXPORT_SYMBOL_PROTO(lseek64);
+ EXPORT_SYMBOL_PROTO(chown);
++EXPORT_SYMBOL_PROTO(fchown);
+ EXPORT_SYMBOL_PROTO(truncate);
++EXPORT_SYMBOL_PROTO(ftruncate64);
+ EXPORT_SYMBOL_PROTO(utime);
++EXPORT_SYMBOL_PROTO(utimes);
++EXPORT_SYMBOL_PROTO(futimes);
+ EXPORT_SYMBOL_PROTO(chmod);
++EXPORT_SYMBOL_PROTO(fchmod);
+ EXPORT_SYMBOL_PROTO(rename);
+ EXPORT_SYMBOL_PROTO(__xmknod);
+
+@@ -102,14 +109,3 @@ EXPORT_SYMBOL(__stack_smash_handler);
+
+ extern long __guard __attribute__((weak));
+ EXPORT_SYMBOL(__guard);
+-
+-/*
+- * Overrides for Emacs so that we follow Linus's tabbing style.
+- * Emacs will notice this stuff at the end of the file and automatically
+- * adjust the settings for this buffer only. This must remain at the end
+- * of the file.
+- * ---------------------------------------------------------------------------
+- * Local variables:
+- * c-file-style: "linux"
+- * End:
+- */
+diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
+index baef5fc..a131d41 100644
+--- a/block/cfq-iosched.c
++++ b/block/cfq-iosched.c
+@@ -92,6 +92,8 @@ struct cfq_data {
+ struct cfq_queue *active_queue;
+ struct cfq_io_context *active_cic;
+
++ struct cfq_queue *async_cfqq[IOPRIO_BE_NR];
++
+ struct timer_list idle_class_timer;
+
+ sector_t last_position;
+@@ -1351,8 +1353,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
+ }
+
+ static struct cfq_queue *
+-cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
+- gfp_t gfp_mask)
++cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync,
++ struct task_struct *tsk, gfp_t gfp_mask)
+ {
+ struct cfq_queue *cfqq, *new_cfqq = NULL;
+ struct cfq_io_context *cic;
+@@ -1405,12 +1407,35 @@ retry:
+ if (new_cfqq)
+ kmem_cache_free(cfq_pool, new_cfqq);
+
+- atomic_inc(&cfqq->ref);
+ out:
+ WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
+ return cfqq;
+ }
+
++static struct cfq_queue *
++cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
++ gfp_t gfp_mask)
++{
++ const int ioprio = task_ioprio(tsk);
++ struct cfq_queue *cfqq = NULL;
++
++ if (!is_sync)
++ cfqq = cfqd->async_cfqq[ioprio];
++ if (!cfqq)
++ cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
++
++ /*
++ * pin the queue now that it's allocated, scheduler exit will prune it
++ */
++ if (!is_sync && !cfqd->async_cfqq[ioprio]) {
++ atomic_inc(&cfqq->ref);
++ cfqd->async_cfqq[ioprio] = cfqq;
++ }
++
++ atomic_inc(&cfqq->ref);
++ return cfqq;
++}
++
+ /*
+ * We drop cfq io contexts lazily, so we may find a dead one.
+ */
+@@ -2019,6 +2044,7 @@ static void cfq_exit_queue(elevator_t *e)
+ {
+ struct cfq_data *cfqd = e->elevator_data;
+ request_queue_t *q = cfqd->queue;
++ int i;
+
+ cfq_shutdown_timer_wq(cfqd);
+
+@@ -2035,6 +2061,13 @@ static void cfq_exit_queue(elevator_t *e)
+ __cfq_exit_single_io_context(cfqd, cic);
+ }
+
++ /*
++ * Put the async queues
++ */
++ for (i = 0; i < IOPRIO_BE_NR; i++)
++ if (cfqd->async_cfqq[i])
++ cfq_put_queue(cfqd->async_cfqq[i]);
++
+ spin_unlock_irq(q->queue_lock);
+
+ cfq_shutdown_timer_wq(cfqd);
+diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
+index 4546bf8..9bc340b 100644
+--- a/drivers/acpi/dock.c
++++ b/drivers/acpi/dock.c
+@@ -716,6 +716,7 @@ static int dock_add(acpi_handle handle)
+ if (ret) {
+ printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret);
+ kfree(dock_station);
++ dock_station = NULL;
+ return ret;
+ }
+ ret = device_create_file(&dock_device.dev, &dev_attr_docked);
+@@ -723,6 +724,7 @@ static int dock_add(acpi_handle handle)
+ printk("Error %d adding sysfs file\n", ret);
+ platform_device_unregister(&dock_device);
+ kfree(dock_station);
++ dock_station = NULL;
+ return ret;
+ }
+ ret = device_create_file(&dock_device.dev, &dev_attr_undock);
+@@ -731,6 +733,7 @@ static int dock_add(acpi_handle handle)
+ device_remove_file(&dock_device.dev, &dev_attr_docked);
+ platform_device_unregister(&dock_device);
+ kfree(dock_station);
++ dock_station = NULL;
+ return ret;
+ }
+ ret = device_create_file(&dock_device.dev, &dev_attr_uid);
+@@ -738,6 +741,7 @@ static int dock_add(acpi_handle handle)
+ printk("Error %d adding sysfs file\n", ret);
+ platform_device_unregister(&dock_device);
+ kfree(dock_station);
++ dock_station = NULL;
+ return ret;
+ }
+
+@@ -750,6 +754,7 @@ static int dock_add(acpi_handle handle)
+ dd = alloc_dock_dependent_device(handle);
+ if (!dd) {
+ kfree(dock_station);
++ dock_station = NULL;
+ ret = -ENOMEM;
+ goto dock_add_err_unregister;
+ }
+@@ -777,6 +782,7 @@ dock_add_err_unregister:
+ device_remove_file(&dock_device.dev, &dev_attr_undock);
+ platform_device_unregister(&dock_device);
+ kfree(dock_station);
++ dock_station = NULL;
+ return ret;
+ }
+
+@@ -810,6 +816,7 @@ static int dock_remove(void)
+
+ /* free dock station memory */
+ kfree(dock_station);
++ dock_station = NULL;
+ return 0;
+ }
+
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 981b397..9ad8caf 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -3800,6 +3800,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
+ { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, },
+ { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
+ { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
++ { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
+
+ /* Devices with NCQ limits */
+
+diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
+index fa1c22c..13c1486 100644
+--- a/drivers/ata/libata-sff.c
++++ b/drivers/ata/libata-sff.c
+@@ -211,6 +211,8 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+ tf->hob_lbal = ioread8(ioaddr->lbal_addr);
+ tf->hob_lbam = ioread8(ioaddr->lbam_addr);
+ tf->hob_lbah = ioread8(ioaddr->lbah_addr);
++ iowrite8(tf->ctl, ioaddr->ctl_addr);
++ ap->last_ctl = tf->ctl;
+ }
+ }
+
+diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
+index 61502bc..63f6e2c 100644
+--- a/drivers/ata/pata_scc.c
++++ b/drivers/ata/pata_scc.c
+@@ -352,6 +352,8 @@ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
+ tf->hob_lbal = in_be32(ioaddr->lbal_addr);
+ tf->hob_lbam = in_be32(ioaddr->lbam_addr);
+ tf->hob_lbah = in_be32(ioaddr->lbah_addr);
++ out_be32(ioaddr->ctl_addr, tf->ctl);
++ ap->last_ctl = tf->ctl;
+ }
+ }
+
+diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
+index fe7ef33..4054507 100644
+--- a/drivers/base/cpu.c
++++ b/drivers/base/cpu.c
+@@ -53,7 +53,7 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
+ ret = count;
+ return ret;
+ }
+-static SYSDEV_ATTR(online, 0600, show_online, store_online);
++static SYSDEV_ATTR(online, 0644, show_online, store_online);
+
+ static void __devinit register_cpu_control(struct cpu *cpu)
+ {
+diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
+index ea52740..786c0d9 100644
+--- a/drivers/char/drm/i915_dma.c
++++ b/drivers/char/drm/i915_dma.c
+@@ -184,6 +184,8 @@ static int i915_initialize(drm_device_t * dev,
+ * private backbuffer/depthbuffer usage.
+ */
+ dev_priv->use_mi_batchbuffer_start = 0;
++ if (IS_I965G(dev)) /* 965 doesn't support older method */
++ dev_priv->use_mi_batchbuffer_start = 1;
+
+ /* Allow hardware batchbuffers unless told otherwise.
+ */
+@@ -517,8 +519,13 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev,
+
+ if (dev_priv->use_mi_batchbuffer_start) {
+ BEGIN_LP_RING(2);
+- OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
+- OUT_RING(batch->start | MI_BATCH_NON_SECURE);
++ if (IS_I965G(dev)) {
++ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
++ OUT_RING(batch->start);
++ } else {
++ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
++ OUT_RING(batch->start | MI_BATCH_NON_SECURE);
++ }
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(4);
+@@ -735,7 +742,8 @@ static int i915_setparam(DRM_IOCTL_ARGS)
+
+ switch (param.param) {
+ case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
+- dev_priv->use_mi_batchbuffer_start = param.value;
++ if (!IS_I965G(dev))
++ dev_priv->use_mi_batchbuffer_start = param.value;
+ break;
+ case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
+ dev_priv->tex_lru_log_granularity = param.value;
+diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
+index 85e323a..44a0717 100644
+--- a/drivers/char/drm/i915_drv.h
++++ b/drivers/char/drm/i915_drv.h
+@@ -282,6 +282,7 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
+ #define MI_BATCH_BUFFER_START (0x31<<23)
+ #define MI_BATCH_BUFFER_END (0xA<<23)
+ #define MI_BATCH_NON_SECURE (1)
++#define MI_BATCH_NON_SECURE_I965 (1<<8)
+
+ #define MI_WAIT_FOR_EVENT ((0x3<<23))
+ #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
+diff --git a/drivers/char/sx.c b/drivers/char/sx.c
+index 1da92a6..85a2328 100644
+--- a/drivers/char/sx.c
++++ b/drivers/char/sx.c
+@@ -2721,9 +2721,9 @@ static void __devexit sx_pci_remove(struct pci_dev *pdev)
+ its because the standard requires it. So check for SUBVENDOR_ID. */
+ static struct pci_device_id sx_pci_tbl[] = {
+ { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
+- .subvendor = 0x0200,.subdevice = PCI_ANY_ID },
++ .subvendor = PCI_ANY_ID, .subdevice = 0x0200 },
+ { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
+- .subvendor = 0x0300,.subdevice = PCI_ANY_ID },
++ .subvendor = PCI_ANY_ID, .subdevice = 0x0300 },
+ { 0 }
+ };
+
+diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
+index 96c8ac5..05a5ff1 100644
+--- a/drivers/firewire/fw-ohci.c
++++ b/drivers/firewire/fw-ohci.c
+@@ -586,7 +586,7 @@ static void context_stop(struct context *ctx)
+ break;
+
+ fw_notify("context_stop: still active (0x%08x)\n", reg);
+- msleep(1);
++ mdelay(1);
+ }
+ }
+
+diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
+index a98d391..a68f7de 100644
+--- a/drivers/firewire/fw-sbp2.c
++++ b/drivers/firewire/fw-sbp2.c
+@@ -985,6 +985,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+ struct fw_unit *unit = sd->unit;
+ struct fw_device *device = fw_device(unit->device.parent);
+ struct sbp2_command_orb *orb;
++ unsigned max_payload;
+
+ /*
+ * Bidirectional commands are not yet implemented, and unknown
+@@ -1023,8 +1024,10 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+ * specifies the max payload size as 2 ^ (max_payload + 2), so
+ * if we set this to max_speed + 7, we get the right value.
+ */
++ max_payload = device->node->max_speed + 7;
++ max_payload = min(max_payload, device->card->max_receive - 1);
+ orb->request.misc =
+- COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) |
++ COMMAND_ORB_MAX_PAYLOAD(max_payload) |
+ COMMAND_ORB_SPEED(device->node->max_speed) |
+ COMMAND_ORB_NOTIFY;
+
+diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
+index 80d0121..a506a1f 100644
+--- a/drivers/firewire/fw-transaction.c
++++ b/drivers/firewire/fw-transaction.c
+@@ -605,8 +605,10 @@ fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
+ * check is sufficient to ensure we don't send response to
+ * broadcast packets or posted writes.
+ */
+- if (request->ack != ACK_PENDING)
++ if (request->ack != ACK_PENDING) {
++ kfree(request);
+ return;
++ }
+
+ if (rcode == RCODE_COMPLETE)
+ fw_fill_response(&request->response, request->request_header,
+diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
+index acdc3be..e2b9ca4 100644
+--- a/drivers/firewire/fw-transaction.h
++++ b/drivers/firewire/fw-transaction.h
+@@ -124,6 +124,10 @@ typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
+ size_t length,
+ void *callback_data);
+
++/*
++ * Important note: The callback must guarantee that either fw_send_response()
++ * or kfree() is called on the @request.
++ */
+ typedef void (*fw_address_callback_t)(struct fw_card *card,
+ struct fw_request *request,
+ int tcode, int destination, int source,
+@@ -228,7 +232,7 @@ struct fw_card {
+ unsigned long reset_jiffies;
+
+ unsigned long long guid;
+- int max_receive;
++ unsigned max_receive;
+ int link_speed;
+ int config_rom_generation;
+
+diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
+index 3f873cc..c7ff28a 100644
+--- a/drivers/ieee1394/sbp2.c
++++ b/drivers/ieee1394/sbp2.c
+@@ -774,11 +774,6 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
+ SBP2_ERR("failed to register lower 4GB address range");
+ goto failed_alloc;
+ }
+-#else
+- if (dma_set_mask(hi->host->device.parent, DMA_32BIT_MASK)) {
+- SBP2_ERR("failed to set 4GB DMA mask");
+- goto failed_alloc;
+- }
+ #endif
+ }
+
+diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
+index 1740cad..91109b4 100644
+--- a/drivers/input/mouse/lifebook.c
++++ b/drivers/input/mouse/lifebook.c
+@@ -109,7 +109,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
+ {
+ struct lifebook_data *priv = psmouse->private;
+ struct input_dev *dev1 = psmouse->dev;
+- struct input_dev *dev2 = priv->dev2;
++ struct input_dev *dev2 = priv ? priv->dev2 : NULL;
+ unsigned char *packet = psmouse->packet;
+ int relative_packet = packet[0] & 0x08;
+
+diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
+index fa17d6d..aee952f 100644
+--- a/drivers/kvm/svm.c
++++ b/drivers/kvm/svm.c
+@@ -1727,6 +1727,12 @@ static void svm_inject_page_fault(struct kvm_vcpu *vcpu,
+
+ static int is_disabled(void)
+ {
++ u64 vm_cr;
++
++ rdmsrl(MSR_VM_CR, vm_cr);
++ if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE))
++ return 1;
++
+ return 0;
+ }
+
+diff --git a/drivers/kvm/svm.h b/drivers/kvm/svm.h
+index 5e93814..3b1b0f3 100644
+--- a/drivers/kvm/svm.h
++++ b/drivers/kvm/svm.h
+@@ -175,8 +175,11 @@ struct __attribute__ ((__packed__)) vmcb {
+ #define SVM_CPUID_FUNC 0x8000000a
+
+ #define MSR_EFER_SVME_MASK (1ULL << 12)
++#define MSR_VM_CR 0xc0010114
+ #define MSR_VM_HSAVE_PA 0xc0010117ULL
+
++#define SVM_VM_CR_SVM_DISABLE 4
++
+ #define SVM_SELECTOR_S_SHIFT 4
+ #define SVM_SELECTOR_DPL_SHIFT 5
+ #define SVM_SELECTOR_P_SHIFT 7
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 7b0fcfc..45e1c31 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -920,6 +920,8 @@ static void crypt_dtr(struct dm_target *ti)
+ {
+ struct crypt_config *cc = (struct crypt_config *) ti->private;
+
++ flush_workqueue(_kcryptd_workqueue);
++
+ bioset_free(cc->bs);
+ mempool_destroy(cc->page_pool);
+ mempool_destroy(cc->io_pool);
+@@ -941,9 +943,6 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
+ struct crypt_config *cc = ti->private;
+ struct crypt_io *io;
+
+- if (bio_barrier(bio))
+- return -EOPNOTSUPP;
+-
+ io = mempool_alloc(cc->io_pool, GFP_NOIO);
+ io->target = ti;
+ io->base_bio = bio;
+diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
+index 07e0a0c..4264f69 100644
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -457,11 +457,6 @@ static int persistent_read_metadata(struct exception_store *store)
+ /*
+ * Sanity checks.
+ */
+- if (!ps->valid) {
+- DMWARN("snapshot is marked invalid");
+- return -EINVAL;
+- }
+-
+ if (ps->version != SNAPSHOT_DISK_VERSION) {
+ DMWARN("unable to handle snapshot disk version %d",
+ ps->version);
+@@ -469,6 +464,12 @@ static int persistent_read_metadata(struct exception_store *store)
+ }
+
+ /*
++ * Metadata are valid, but snapshot is invalidated
++ */
++ if (!ps->valid)
++ return 1;
++
++ /*
+ * Read the metadata.
+ */
+ r = read_exceptions(ps);
+diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
+index 352c6fb..f3a7724 100644
+--- a/drivers/md/dm-io.c
++++ b/drivers/md/dm-io.c
+@@ -293,7 +293,10 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
+ * bvec for bio_get/set_region() and decrement bi_max_vecs
+ * to hide it from bio_add_page().
+ */
+- num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2;
++ num_bvecs = dm_sector_div_up(remaining,
++ (PAGE_SIZE >> SECTOR_SHIFT));
++ num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev),
++ num_bvecs);
+ bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
+ bio->bi_sector = where->sector + (where->count - remaining);
+ bio->bi_bdev = where->bdev;
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index de54b39..bfb2ea3 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -798,9 +798,6 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
+ struct mpath_io *mpio;
+ struct multipath *m = (struct multipath *) ti->private;
+
+- if (bio_barrier(bio))
+- return -EOPNOTSUPP;
+-
+ mpio = mempool_alloc(m->mpio_pool, GFP_NOIO);
+ dm_bio_record(&mpio->details, bio);
+
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index ef124b7..7113af3 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -1288,12 +1288,12 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
+ for (m = 0; m < ms->nr_mirrors; m++)
+ DMEMIT("%s ", ms->mirror[m].dev->name);
+
+- DMEMIT("%llu/%llu",
++ DMEMIT("%llu/%llu 0 ",
+ (unsigned long long)ms->rh.log->type->
+ get_sync_count(ms->rh.log),
+ (unsigned long long)ms->nr_regions);
+
+- sz = ms->rh.log->type->status(ms->rh.log, type, result, maxlen);
++ sz += ms->rh.log->type->status(ms->rh.log, type, result+sz, maxlen-sz);
+
+ break;
+
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index 0821a2b..3955621 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -522,9 +522,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+
+ /* Metadata must only be loaded into one table at once */
+ r = s->store.read_metadata(&s->store);
+- if (r) {
++ if (r < 0) {
+ ti->error = "Failed to read snapshot metadata";
+ goto bad6;
++ } else if (r > 0) {
++ s->valid = 0;
++ DMWARN("Snapshot is marked invalid.");
+ }
+
+ bio_list_init(&s->queued_bios);
+@@ -884,9 +887,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
+ if (!s->valid)
+ return -EIO;
+
+- if (unlikely(bio_barrier(bio)))
+- return -EOPNOTSUPP;
+-
+ /* FIXME: should only take write lock if we need
+ * to copy an exception */
+ down_write(&s->lock);
+@@ -1157,9 +1157,6 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
+ struct dm_dev *dev = (struct dm_dev *) ti->private;
+ bio->bi_bdev = dev->bdev;
+
+- if (unlikely(bio_barrier(bio)))
+- return -EOPNOTSUPP;
+-
+ /* Only tell snapshots if this is a write */
+ return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED;
+ }
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 2717a35..75bd2fd 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -802,6 +802,15 @@ static int dm_request(request_queue_t *q, struct bio *bio)
+ int rw = bio_data_dir(bio);
+ struct mapped_device *md = q->queuedata;
+
++ /*
++ * There is no use in forwarding any barrier request since we can't
++ * guarantee it is (or can be) handled by the targets correctly.
++ */
++ if (unlikely(bio_barrier(bio))) {
++ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
++ return 0;
++ }
++
+ down_read(&md->io_lock);
+
+ disk_stat_inc(dm_disk(md), ios[rw]);
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 9eb66c1..e0029ea 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -917,6 +917,13 @@ static int make_request(request_queue_t *q, struct bio * bio)
+ bio_list_add(&bl, mbio);
+ }
+
++ if (unlikely(!atomic_read(&r10_bio->remaining))) {
++ /* the array is dead */
++ md_write_end(mddev);
++ raid_end_bio_io(r10_bio);
++ return 0;
++ }
++
+ bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0);
+ spin_lock_irqsave(&conf->device_lock, flags);
+ bio_list_merge(&conf->pending_bio_list, &bl);
+@@ -1558,7 +1565,6 @@ static void raid10d(mddev_t *mddev)
+ bio = r10_bio->devs[r10_bio->read_slot].bio;
+ r10_bio->devs[r10_bio->read_slot].bio =
+ mddev->ro ? IO_BLOCKED : NULL;
+- bio_put(bio);
+ mirror = read_balance(conf, r10_bio);
+ if (mirror == -1) {
+ printk(KERN_ALERT "raid10: %s: unrecoverable I/O"
+@@ -1566,8 +1572,10 @@ static void raid10d(mddev_t *mddev)
+ bdevname(bio->bi_bdev,b),
+ (unsigned long long)r10_bio->sector);
+ raid_end_bio_io(r10_bio);
++ bio_put(bio);
+ } else {
+ const int do_sync = bio_sync(r10_bio->master_bio);
++ bio_put(bio);
+ rdev = conf->mirrors[mirror].rdev;
+ if (printk_ratelimit())
+ printk(KERN_ERR "raid10: %s: redirecting sector %llu to"
+diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
+index efc6635..5d9de5d 100644
+--- a/drivers/media/video/ivtv/ivtv-driver.c
++++ b/drivers/media/video/ivtv/ivtv-driver.c
+@@ -622,6 +622,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
+ itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
+ itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
+
++ mutex_init(&itv->serialize_lock);
+ mutex_init(&itv->i2c_bus_lock);
+ mutex_init(&itv->udma.lock);
+
+diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
+index e6e56f1..65ebdda 100644
+--- a/drivers/media/video/ivtv/ivtv-driver.h
++++ b/drivers/media/video/ivtv/ivtv-driver.h
+@@ -650,7 +650,6 @@ struct vbi_info {
+ /* convenience pointer to sliced struct in vbi_in union */
+ struct v4l2_sliced_vbi_format *sliced_in;
+ u32 service_set_in;
+- u32 service_set_out;
+ int insert_mpeg;
+
+ /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
+@@ -723,6 +722,7 @@ struct ivtv {
+ int search_pack_header;
+
+ spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
++ struct mutex serialize_lock; /* lock used to serialize starting streams */
+
+ /* User based DMA for OSD */
+ struct ivtv_user_dma udma;
+diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
+index ba98bf0..e83b496 100644
+--- a/drivers/media/video/ivtv/ivtv-irq.c
++++ b/drivers/media/video/ivtv/ivtv-irq.c
+@@ -403,6 +403,11 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
+ /* Mark last buffer size for Interrupt flag */
+ s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
+
++ if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
++ set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
++ else
++ clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
++
+ if (ivtv_use_pio(s)) {
+ for (i = 0; i < s->SG_length; i++) {
+ s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
+@@ -597,7 +602,6 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
+ data[0], data[1], data[2]);
+ return;
+ }
+- clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+ s = &itv->streams[ivtv_stream_map[data[0]]];
+ if (!stream_enc_dma_append(s, data)) {
+ set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
+@@ -634,7 +638,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
+ then start a DMA request for just the VBI data. */
+ if (!stream_enc_dma_append(s, data) &&
+ !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
+- set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+ set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
+ }
+ }
+diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
+index 6af88ae..d538efa 100644
+--- a/drivers/media/video/ivtv/ivtv-streams.c
++++ b/drivers/media/video/ivtv/ivtv-streams.c
+@@ -446,6 +446,9 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
+ if (s->v4l2dev == NULL)
+ return -EINVAL;
+
++ /* Big serialization lock to ensure no two streams are started
++ simultaneously: that can give all sorts of weird results. */
++ mutex_lock(&itv->serialize_lock);
+ IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
+
+ switch (s->type) {
+@@ -487,6 +490,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
+ 0, sizeof(itv->vbi.sliced_mpeg_size));
+ break;
+ default:
++ mutex_unlock(&itv->serialize_lock);
+ return -EINVAL;
+ }
+ s->subtype = subtype;
+@@ -568,6 +572,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
+ if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype))
+ {
+ IVTV_DEBUG_WARN( "Error starting capture!\n");
++ mutex_unlock(&itv->serialize_lock);
+ return -EINVAL;
+ }
+
+@@ -583,6 +588,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
+
+ /* you're live! sit back and await interrupts :) */
+ atomic_inc(&itv->capturing);
++ mutex_unlock(&itv->serialize_lock);
+ return 0;
+ }
+
+@@ -762,17 +768,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
+ /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */
+ ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype);
+
+- /* only run these if we're shutting down the last cap */
+- if (atomic_read(&itv->capturing) - 1 == 0) {
+- /* event notification (off) */
+- if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
+- /* type: 0 = refresh */
+- /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */
+- ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1);
+- ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
+- }
+- }
+-
+ then = jiffies;
+
+ if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
+@@ -840,17 +835,30 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
+ /* Clear capture and no-read bits */
+ clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
+
++ /* ensure these global cleanup actions are done only once */
++ mutex_lock(&itv->serialize_lock);
++
+ if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
+ ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
+
+ if (atomic_read(&itv->capturing) > 0) {
++ mutex_unlock(&itv->serialize_lock);
+ return 0;
+ }
+
+ /* Set the following Interrupt mask bits for capture */
+ ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
+
++ /* event notification (off) */
++ if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
++ /* type: 0 = refresh */
++ /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */
++ ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1);
++ ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
++ }
++
+ wake_up(&s->waitq);
++ mutex_unlock(&itv->serialize_lock);
+
+ return 0;
+ }
+diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
+index 3ba46e0..a7282a9 100644
+--- a/drivers/media/video/ivtv/ivtv-vbi.c
++++ b/drivers/media/video/ivtv/ivtv-vbi.c
+@@ -219,31 +219,23 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
+ int found_cc = 0;
+ int cc_pos = itv->vbi.cc_pos;
+
+- if (itv->vbi.service_set_out == 0)
+- return -EPERM;
+-
+ while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
+ switch (p->id) {
+ case V4L2_SLICED_CAPTION_525:
+- if (p->id == V4L2_SLICED_CAPTION_525 &&
+- p->line == 21 &&
+- (itv->vbi.service_set_out &
+- V4L2_SLICED_CAPTION_525) == 0) {
+- break;
+- }
+- found_cc = 1;
+- if (p->field) {
+- cc[2] = p->data[0];
+- cc[3] = p->data[1];
+- } else {
+- cc[0] = p->data[0];
+- cc[1] = p->data[1];
++ if (p->line == 21) {
++ found_cc = 1;
++ if (p->field) {
++ cc[2] = p->data[0];
++ cc[3] = p->data[1];
++ } else {
++ cc[0] = p->data[0];
++ cc[1] = p->data[1];
++ }
+ }
+ break;
+
+ case V4L2_SLICED_VPS:
+- if (p->line == 16 && p->field == 0 &&
+- (itv->vbi.service_set_out & V4L2_SLICED_VPS)) {
++ if (p->line == 16 && p->field == 0) {
+ itv->vbi.vps[0] = p->data[2];
+ itv->vbi.vps[1] = p->data[8];
+ itv->vbi.vps[2] = p->data[9];
+@@ -255,8 +247,7 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
+ break;
+
+ case V4L2_SLICED_WSS_625:
+- if (p->line == 23 && p->field == 0 &&
+- (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) {
++ if (p->line == 23 && p->field == 0) {
+ /* No lock needed for WSS */
+ itv->vbi.wss = p->data[0] | (p->data[1] << 8);
+ itv->vbi.wss_found = 1;
+diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
+index 13ee550..d2915d3 100644
+--- a/drivers/media/video/v4l2-common.c
++++ b/drivers/media/video/v4l2-common.c
+@@ -939,16 +939,25 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
+ When no more controls are available 0 is returned. */
+ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
+ {
+- u32 ctrl_class;
++ u32 ctrl_class = V4L2_CTRL_ID2CLASS(id);
+ const u32 *pctrl;
+
+- /* if no query is desired, then just return the control ID */
+- if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0)
+- return id;
+ if (ctrl_classes == NULL)
+ return 0;
++
++ /* if no query is desired, then check if the ID is part of ctrl_classes */
++ if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) {
++ /* find class */
++ while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class)
++ ctrl_classes++;
++ if (*ctrl_classes == NULL)
++ return 0;
++ pctrl = *ctrl_classes;
++ /* find control ID */
++ while (*pctrl && *pctrl != id) pctrl++;
++ return *pctrl ? id : 0;
++ }
+ id &= V4L2_CTRL_ID_MASK;
+- ctrl_class = V4L2_CTRL_ID2CLASS(id);
+ id++; /* select next control */
+ /* find first class that matches (or is greater than) the class of
+ the ID */
+diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
+index 8f6741a..1bf4cbe 100644
+--- a/drivers/media/video/wm8739.c
++++ b/drivers/media/video/wm8739.c
+@@ -321,12 +321,14 @@ static int wm8739_probe(struct i2c_adapter *adapter)
+
+ static int wm8739_detach(struct i2c_client *client)
+ {
++ struct wm8739_state *state = i2c_get_clientdata(client);
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err)
+ return err;
+
++ kfree(state);
+ kfree(client);
+ return 0;
+ }
+diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
+index 4df5d30..9f7e894 100644
+--- a/drivers/media/video/wm8775.c
++++ b/drivers/media/video/wm8775.c
+@@ -222,12 +222,14 @@ static int wm8775_probe(struct i2c_adapter *adapter)
+
+ static int wm8775_detach(struct i2c_client *client)
+ {
++ struct wm8775_state *state = i2c_get_clientdata(client);
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err) {
+ return err;
+ }
++ kfree(state);
+ kfree(client);
+
+ return 0;
+diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
+index 8ee0321..ab2ca63 100644
+--- a/drivers/misc/sony-laptop.c
++++ b/drivers/misc/sony-laptop.c
+@@ -908,7 +908,9 @@ static struct acpi_driver sony_nc_driver = {
+ #define SONYPI_DEVICE_TYPE2 0x00000002
+ #define SONYPI_DEVICE_TYPE3 0x00000004
+
+-#define SONY_PIC_EV_MASK 0xff
++#define SONYPI_TYPE1_OFFSET 0x04
++#define SONYPI_TYPE2_OFFSET 0x12
++#define SONYPI_TYPE3_OFFSET 0x12
+
+ struct sony_pic_ioport {
+ struct acpi_resource_io io;
+@@ -922,6 +924,7 @@ struct sony_pic_irq {
+
+ struct sony_pic_dev {
+ int model;
++ u16 evport_offset;
+ u8 camera_power;
+ u8 bluetooth_power;
+ u8 wwan_power;
+@@ -1998,20 +2001,17 @@ end:
+ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
+ {
+ int i, j;
+- u32 port_val = 0;
+ u8 ev = 0;
+ u8 data_mask = 0;
+ u8 device_event = 0;
+
+ struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
+
+- acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val,
+- dev->cur_ioport->io.address_length);
+- ev = port_val & SONY_PIC_EV_MASK;
+- data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8));
++ ev = inb_p(dev->cur_ioport->io.minimum);
++ data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
+
+- dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n",
+- port_val, ev, data_mask, dev->cur_ioport->io.minimum);
++ dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
++ ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
+
+ if (ev == 0x00 || ev == 0xff)
+ return IRQ_HANDLED;
+@@ -2102,6 +2102,20 @@ static int sony_pic_add(struct acpi_device *device)
+ spic_dev.model = sony_pic_detect_device_type();
+ mutex_init(&spic_dev.lock);
+
++ /* model specific characteristics */
++ switch(spic_dev.model) {
++ case SONYPI_DEVICE_TYPE1:
++ spic_dev.evport_offset = SONYPI_TYPE1_OFFSET;
++ break;
++ case SONYPI_DEVICE_TYPE3:
++ spic_dev.evport_offset = SONYPI_TYPE3_OFFSET;
++ break;
++ case SONYPI_DEVICE_TYPE2:
++ default:
++ spic_dev.evport_offset = SONYPI_TYPE2_OFFSET;
++ break;
++ }
++
+ /* read _PRS resources */
+ result = sony_pic_possible_resources(device);
+ if (result) {
+diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
+index 42ba1c0..a361dba 100644
+--- a/drivers/net/forcedeth.c
++++ b/drivers/net/forcedeth.c
+@@ -550,6 +550,8 @@ union ring_type {
+ /* PHY defines */
+ #define PHY_OUI_MARVELL 0x5043
+ #define PHY_OUI_CICADA 0x03f1
++#define PHY_OUI_VITESSE 0x01c1
++#define PHY_OUI_REALTEK 0x01c1
+ #define PHYID1_OUI_MASK 0x03ff
+ #define PHYID1_OUI_SHFT 6
+ #define PHYID2_OUI_MASK 0xfc00
+@@ -557,12 +559,36 @@ union ring_type {
+ #define PHYID2_MODEL_MASK 0x03f0
+ #define PHY_MODEL_MARVELL_E3016 0x220
+ #define PHY_MARVELL_E3016_INITMASK 0x0300
+-#define PHY_INIT1 0x0f000
+-#define PHY_INIT2 0x0e00
+-#define PHY_INIT3 0x01000
+-#define PHY_INIT4 0x0200
+-#define PHY_INIT5 0x0004
+-#define PHY_INIT6 0x02000
++#define PHY_CICADA_INIT1 0x0f000
++#define PHY_CICADA_INIT2 0x0e00
++#define PHY_CICADA_INIT3 0x01000
++#define PHY_CICADA_INIT4 0x0200
++#define PHY_CICADA_INIT5 0x0004
++#define PHY_CICADA_INIT6 0x02000
++#define PHY_VITESSE_INIT_REG1 0x1f
++#define PHY_VITESSE_INIT_REG2 0x10
++#define PHY_VITESSE_INIT_REG3 0x11
++#define PHY_VITESSE_INIT_REG4 0x12
++#define PHY_VITESSE_INIT_MSK1 0xc
++#define PHY_VITESSE_INIT_MSK2 0x0180
++#define PHY_VITESSE_INIT1 0x52b5
++#define PHY_VITESSE_INIT2 0xaf8a
++#define PHY_VITESSE_INIT3 0x8
++#define PHY_VITESSE_INIT4 0x8f8a
++#define PHY_VITESSE_INIT5 0xaf86
++#define PHY_VITESSE_INIT6 0x8f86
++#define PHY_VITESSE_INIT7 0xaf82
++#define PHY_VITESSE_INIT8 0x0100
++#define PHY_VITESSE_INIT9 0x8f82
++#define PHY_VITESSE_INIT10 0x0
++#define PHY_REALTEK_INIT_REG1 0x1f
++#define PHY_REALTEK_INIT_REG2 0x19
++#define PHY_REALTEK_INIT_REG3 0x13
++#define PHY_REALTEK_INIT1 0x0000
++#define PHY_REALTEK_INIT2 0x8e00
++#define PHY_REALTEK_INIT3 0x0001
++#define PHY_REALTEK_INIT4 0xad17
++
+ #define PHY_GIGABIT 0x0100
+
+ #define PHY_TIMEOUT 0x1
+@@ -1096,6 +1122,28 @@ static int phy_init(struct net_device *dev)
+ return PHY_ERROR;
+ }
+ }
++ if (np->phy_oui == PHY_OUI_REALTEK) {
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ }
+
+ /* set advertise register */
+ reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
+@@ -1141,14 +1189,14 @@ static int phy_init(struct net_device *dev)
+ /* phy vendor specific configuration */
+ if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) {
+ phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
+- phy_reserved &= ~(PHY_INIT1 | PHY_INIT2);
+- phy_reserved |= (PHY_INIT3 | PHY_INIT4);
++ phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
++ phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
+ if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
+- phy_reserved |= PHY_INIT5;
++ phy_reserved |= PHY_CICADA_INIT5;
+ if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+@@ -1156,12 +1204,106 @@ static int phy_init(struct net_device *dev)
+ }
+ if (np->phy_oui == PHY_OUI_CICADA) {
+ phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ);
+- phy_reserved |= PHY_INIT6;
++ phy_reserved |= PHY_CICADA_INIT6;
+ if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ }
++ if (np->phy_oui == PHY_OUI_VITESSE) {
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
++ phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
++ phy_reserved |= PHY_VITESSE_INIT3;
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
++ phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
++ phy_reserved |= PHY_VITESSE_INIT3;
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
++ phy_reserved &= ~PHY_VITESSE_INIT_MSK2;
++ phy_reserved |= PHY_VITESSE_INIT8;
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ }
++ if (np->phy_oui == PHY_OUI_REALTEK) {
++ /* reset could have cleared these out, set them back */
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
++ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
++ return PHY_ERROR;
++ }
++ }
++
+ /* some phys clear out pause advertisment on reset, set it back */
+ mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg);
+
+diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
+index 50cad3a..1e03bbd 100644
+--- a/drivers/pcmcia/cs.c
++++ b/drivers/pcmcia/cs.c
+@@ -409,6 +409,9 @@ static void socket_shutdown(struct pcmcia_socket *s)
+ #endif
+ s->functions = 0;
+
++ /* give socket some time to power down */
++ msleep(100);
++
+ s->ops->get_status(s, &status);
+ if (status & SS_POWERON) {
+ printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
+index 5c487ff..ac65ee2 100644
+--- a/drivers/scsi/aacraid/linit.c
++++ b/drivers/scsi/aacraid/linit.c
+@@ -597,6 +597,8 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
+ static int aac_cfg_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+ {
++ if (!capable(CAP_SYS_ADMIN))
++ return -EPERM;
+ return aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
+ }
+
+@@ -650,6 +652,8 @@ static int aac_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+
+ static long aac_compat_cfg_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+ {
++ if (!capable(CAP_SYS_ADMIN))
++ return -EPERM;
+ return aac_compat_do_ioctl((struct aac_dev *)file->private_data, cmd, arg);
+ }
+ #endif
+diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
+index 96557e6..17bcca5 100644
+--- a/drivers/serial/sunhv.c
++++ b/drivers/serial/sunhv.c
+@@ -440,8 +440,16 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign
+ {
+ struct uart_port *port = sunhv_port;
+ unsigned long flags;
++ int locked = 1;
++
++ local_irq_save(flags);
++ if (port->sysrq) {
++ locked = 0;
++ } else if (oops_in_progress) {
++ locked = spin_trylock(&port->lock);
++ } else
++ spin_lock(&port->lock);
+
+- spin_lock_irqsave(&port->lock, flags);
+ while (n > 0) {
+ unsigned long ra = __pa(con_write_page);
+ unsigned long page_bytes;
+@@ -469,7 +477,10 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign
+ ra += written;
+ }
+ }
+- spin_unlock_irqrestore(&port->lock, flags);
++
++ if (locked)
++ spin_unlock(&port->lock);
++ local_irq_restore(flags);
+ }
+
+ static inline void sunhv_console_putchar(struct uart_port *port, char c)
+@@ -488,7 +499,15 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
+ {
+ struct uart_port *port = sunhv_port;
+ unsigned long flags;
+- int i;
++ int i, locked = 1;
++
++ local_irq_save(flags);
++ if (port->sysrq) {
++ locked = 0;
++ } else if (oops_in_progress) {
++ locked = spin_trylock(&port->lock);
++ } else
++ spin_lock(&port->lock);
+
+ spin_lock_irqsave(&port->lock, flags);
+ for (i = 0; i < n; i++) {
+@@ -496,7 +515,10 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
+ sunhv_console_putchar(port, '\r');
+ sunhv_console_putchar(port, *s++);
+ }
+- spin_unlock_irqrestore(&port->lock, flags);
++
++ if (locked)
++ spin_unlock(&port->lock);
++ local_irq_restore(flags);
+ }
+
+ static struct console sunhv_console = {
+diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
+index deb9ab4..8a0f9e4 100644
+--- a/drivers/serial/sunsab.c
++++ b/drivers/serial/sunsab.c
+@@ -860,22 +860,31 @@ static int num_channels;
+ static void sunsab_console_putchar(struct uart_port *port, int c)
+ {
+ struct uart_sunsab_port *up = (struct uart_sunsab_port *)port;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&up->port.lock, flags);
+
+ sunsab_tec_wait(up);
+ writeb(c, &up->regs->w.tic);
+-
+- spin_unlock_irqrestore(&up->port.lock, flags);
+ }
+
+ static void sunsab_console_write(struct console *con, const char *s, unsigned n)
+ {
+ struct uart_sunsab_port *up = &sunsab_ports[con->index];
++ unsigned long flags;
++ int locked = 1;
++
++ local_irq_save(flags);
++ if (up->port.sysrq) {
++ locked = 0;
++ } else if (oops_in_progress) {
++ locked = spin_trylock(&up->port.lock);
++ } else
++ spin_lock(&up->port.lock);
+
+ uart_console_write(&up->port, s, n, sunsab_console_putchar);
+ sunsab_tec_wait(up);
++
++ if (locked)
++ spin_unlock(&up->port.lock);
++ local_irq_restore(flags);
+ }
+
+ static int sunsab_console_setup(struct console *con, char *options)
+diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
+index 2a63cdb..26d720b 100644
+--- a/drivers/serial/sunsu.c
++++ b/drivers/serial/sunsu.c
+@@ -1288,7 +1288,17 @@ static void sunsu_console_write(struct console *co, const char *s,
+ unsigned int count)
+ {
+ struct uart_sunsu_port *up = &sunsu_ports[co->index];
++ unsigned long flags;
+ unsigned int ier;
++ int locked = 1;
++
++ local_irq_save(flags);
++ if (up->port.sysrq) {
++ locked = 0;
++ } else if (oops_in_progress) {
++ locked = spin_trylock(&up->port.lock);
++ } else
++ spin_lock(&up->port.lock);
+
+ /*
+ * First save the UER then disable the interrupts
+@@ -1304,6 +1314,10 @@ static void sunsu_console_write(struct console *co, const char *s,
+ */
+ wait_for_xmitr(up);
+ serial_out(up, UART_IER, ier);
++
++ if (locked)
++ spin_unlock(&up->port.lock);
++ local_irq_restore(flags);
+ }
+
+ /*
+diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
+index 15b6e1c..0a3e10a 100644
+--- a/drivers/serial/sunzilog.c
++++ b/drivers/serial/sunzilog.c
+@@ -9,7 +9,7 @@
+ * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their
+ * work there.
+ *
+- * Copyright (C) 2002, 2006 David S. Miller (davem at davemloft.net)
++ * Copyright (C) 2002, 2006, 2007 David S. Miller (davem at davemloft.net)
+ */
+
+ #include <linux/module.h>
+@@ -1151,11 +1151,22 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count)
+ {
+ struct uart_sunzilog_port *up = &sunzilog_port_table[con->index];
+ unsigned long flags;
++ int locked = 1;
++
++ local_irq_save(flags);
++ if (up->port.sysrq) {
++ locked = 0;
++ } else if (oops_in_progress) {
++ locked = spin_trylock(&up->port.lock);
++ } else
++ spin_lock(&up->port.lock);
+
+- spin_lock_irqsave(&up->port.lock, flags);
+ uart_console_write(&up->port, s, count, sunzilog_putchar);
+ udelay(2);
+- spin_unlock_irqrestore(&up->port.lock, flags);
++
++ if (locked)
++ spin_unlock(&up->port.lock);
++ local_irq_restore(flags);
+ }
+
+ static int __init sunzilog_console_setup(struct console *con, char *options)
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 0081c1d..407fb8f 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -919,6 +919,10 @@ skip_normal_probe:
+ return -EINVAL;
+ }
+ }
++
++ /* Accept probe requests only for the control interface */
++ if (intf != control_interface)
++ return -ENODEV;
+
+ if (usb_interface_claimed(data_interface)) { /* valid in this context */
+ dev_dbg(&intf->dev,"The data interface isn't available");
+@@ -1107,10 +1111,12 @@ static void acm_disconnect(struct usb_interface *intf)
+ return;
+ }
+ if (acm->country_codes){
+- device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
+- device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate);
++ device_remove_file(&acm->control->dev,
++ &dev_attr_wCountryCodes);
++ device_remove_file(&acm->control->dev,
++ &dev_attr_iCountryCodeRelDate);
+ }
+- device_remove_file(&intf->dev, &dev_attr_bmCapabilities);
++ device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
+ acm->dev = NULL;
+ usb_set_intfdata(acm->control, NULL);
+ usb_set_intfdata(acm->data, NULL);
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 24f10a1..a1c1a11 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1388,6 +1388,10 @@ int usb_new_device(struct usb_device *udev)
+ udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
+ (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
+
++ /* Increment the parent's count of unsuspended children */
++ if (udev->parent)
++ usb_autoresume_device(udev->parent);
++
+ /* Register the device. The device driver is responsible
+ * for adding the device files to sysfs and for configuring
+ * the device.
+@@ -1395,13 +1399,11 @@ int usb_new_device(struct usb_device *udev)
+ err = device_add(&udev->dev);
+ if (err) {
+ dev_err(&udev->dev, "can't device_add, error %d\n", err);
++ if (udev->parent)
++ usb_autosuspend_device(udev->parent);
+ goto fail;
+ }
+
+- /* Increment the parent's count of unsuspended children */
+- if (udev->parent)
+- usb_autoresume_device(udev->parent);
+-
+ exit:
+ return err;
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index da1c6f7..38c4e97 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -271,26 +271,58 @@ static int debug;
+ static __u16 vendor = FTDI_VID;
+ static __u16 product;
+
++struct ftdi_private {
++ ftdi_chip_type_t chip_type;
++ /* type of the device, either SIO or FT8U232AM */
++ int baud_base; /* baud base clock for divisor setting */
++ int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
++ __u16 last_set_data_urb_value ;
++ /* the last data state set - needed for doing a break */
++ int write_offset; /* This is the offset in the usb data block to write the serial data -
++ * it is different between devices
++ */
++ int flags; /* some ASYNC_xxxx flags are supported */
++ unsigned long last_dtr_rts; /* saved modem control outputs */
++ wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
++ char prev_status, diff_status; /* Used for TIOCMIWAIT */
++ __u8 rx_flags; /* receive state flags (throttling) */
++ spinlock_t rx_lock; /* spinlock for receive state */
++ struct delayed_work rx_work;
++ struct usb_serial_port *port;
++ int rx_processed;
++ unsigned long rx_bytes;
++
++ __u16 interface; /* FT2232C port interface (0 for FT232/245) */
++
++ int force_baud; /* if non-zero, force the baud rate to this value */
++ int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
++
++ spinlock_t tx_lock; /* spinlock for transmit state */
++ unsigned long tx_bytes;
++ unsigned long tx_outstanding_bytes;
++ unsigned long tx_outstanding_urbs;
++};
++
+ /* struct ftdi_sio_quirk is used by devices requiring special attention. */
+ struct ftdi_sio_quirk {
+ int (*probe)(struct usb_serial *);
+- void (*setup)(struct usb_serial *); /* Special settings during startup. */
++ void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */
+ };
+
+ static int ftdi_olimex_probe (struct usb_serial *serial);
+-static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
+-static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
++static void ftdi_USB_UIRT_setup (struct ftdi_private *priv);
++static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv);
+
+ static struct ftdi_sio_quirk ftdi_olimex_quirk = {
+ .probe = ftdi_olimex_probe,
+ };
+
+ static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
+- .setup = ftdi_USB_UIRT_setup,
++ .port_probe = ftdi_USB_UIRT_setup,
+ };
+
+ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
+- .setup = ftdi_HE_TIRA1_setup,
++ .port_probe = ftdi_HE_TIRA1_setup,
+ };
+
+ /*
+@@ -567,38 +599,6 @@ static const char *ftdi_chip_name[] = {
+ #define THROTTLED 0x01
+ #define ACTUALLY_THROTTLED 0x02
+
+-struct ftdi_private {
+- ftdi_chip_type_t chip_type;
+- /* type of the device, either SIO or FT8U232AM */
+- int baud_base; /* baud base clock for divisor setting */
+- int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
+- __u16 last_set_data_urb_value ;
+- /* the last data state set - needed for doing a break */
+- int write_offset; /* This is the offset in the usb data block to write the serial data -
+- * it is different between devices
+- */
+- int flags; /* some ASYNC_xxxx flags are supported */
+- unsigned long last_dtr_rts; /* saved modem control outputs */
+- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+- char prev_status, diff_status; /* Used for TIOCMIWAIT */
+- __u8 rx_flags; /* receive state flags (throttling) */
+- spinlock_t rx_lock; /* spinlock for receive state */
+- struct delayed_work rx_work;
+- struct usb_serial_port *port;
+- int rx_processed;
+- unsigned long rx_bytes;
+-
+- __u16 interface; /* FT2232C port interface (0 for FT232/245) */
+-
+- int force_baud; /* if non-zero, force the baud rate to this value */
+- int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
+-
+- spinlock_t tx_lock; /* spinlock for transmit state */
+- unsigned long tx_bytes;
+- unsigned long tx_outstanding_bytes;
+- unsigned long tx_outstanding_urbs;
+-};
+-
+ /* Used for TIOCMIWAIT */
+ #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
+ #define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
+@@ -609,7 +609,6 @@ struct ftdi_private {
+
+ /* function prototypes for a FTDI serial converter */
+ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
+-static int ftdi_sio_attach (struct usb_serial *serial);
+ static void ftdi_shutdown (struct usb_serial *serial);
+ static int ftdi_sio_port_probe (struct usb_serial_port *port);
+ static int ftdi_sio_port_remove (struct usb_serial_port *port);
+@@ -663,7 +662,6 @@ static struct usb_serial_driver ftdi_sio_device = {
+ .ioctl = ftdi_ioctl,
+ .set_termios = ftdi_set_termios,
+ .break_ctl = ftdi_break_ctl,
+- .attach = ftdi_sio_attach,
+ .shutdown = ftdi_shutdown,
+ };
+
+@@ -1198,6 +1196,8 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id
+ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ {
+ struct ftdi_private *priv;
++ struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
++
+
+ dbg("%s",__FUNCTION__);
+
+@@ -1214,6 +1214,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ than queue a task to deliver them */
+ priv->flags = ASYNC_LOW_LATENCY;
+
++ if (quirk && quirk->port_probe)
++ quirk->port_probe(priv);
++
+ /* Increase the size of read buffers */
+ kfree(port->bulk_in_buffer);
+ port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
+@@ -1244,29 +1247,13 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ return 0;
+ }
+
+-/* attach subroutine */
+-static int ftdi_sio_attach (struct usb_serial *serial)
+-{
+- /* Check for device requiring special set up. */
+- struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
+-
+- if (quirk && quirk->setup)
+- quirk->setup(serial);
+-
+- return 0;
+-} /* ftdi_sio_attach */
+-
+-
+ /* Setup for the USB-UIRT device, which requires hardwired
+ * baudrate (38400 gets mapped to 312500) */
+ /* Called from usbserial:serial_probe */
+-static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
++static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
+ {
+- struct ftdi_private *priv;
+-
+ dbg("%s",__FUNCTION__);
+
+- priv = usb_get_serial_port_data(serial->port[0]);
+ priv->flags |= ASYNC_SPD_CUST;
+ priv->custom_divisor = 77;
+ priv->force_baud = B38400;
+@@ -1274,13 +1261,10 @@ static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
+
+ /* Setup for the HE-TIRA1 device, which requires hardwired
+ * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */
+-static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
++static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
+ {
+- struct ftdi_private *priv;
+-
+ dbg("%s",__FUNCTION__);
+
+- priv = usb_get_serial_port_data(serial->port[0]);
+ priv->flags |= ASYNC_SPD_CUST;
+ priv->custom_divisor = 240;
+ priv->force_baud = B38400;
+diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
+index 056e192..0f99e07 100644
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -2366,9 +2366,8 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa
+ int status;
+ unsigned char number = edge_port->port->number - edge_port->port->serial->minor;
+
+- if ((!edge_serial->is_epic) ||
+- ((edge_serial->is_epic) &&
+- (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) {
++ if (edge_serial->is_epic &&
++ !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) {
+ dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d",
+ edge_port->port->number, baudRate);
+ return 0;
+@@ -2461,18 +2460,16 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r
+
+ dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue);
+
+- if ((!edge_serial->is_epic) ||
+- ((edge_serial->is_epic) &&
+- (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) &&
+- (regNum == MCR))) {
++ if (edge_serial->is_epic &&
++ !edge_serial->epic_descriptor.Supports.IOSPWriteMCR &&
++ regNum == MCR) {
+ dbg("SendCmdWriteUartReg - Not writing to MCR Register");
+ return 0;
+ }
+
+- if ((!edge_serial->is_epic) ||
+- ((edge_serial->is_epic) &&
+- (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) &&
+- (regNum == LCR))) {
++ if (edge_serial->is_epic &&
++ !edge_serial->epic_descriptor.Supports.IOSPWriteLCR &&
++ regNum == LCR) {
+ dbg ("SendCmdWriteUartReg - Not writing to LCR Register");
+ return 0;
+ }
+diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
+index e9bbc34..1b3f658 100644
+--- a/drivers/video/backlight/cr_bllcd.c
++++ b/drivers/video/backlight/cr_bllcd.c
+@@ -174,7 +174,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
+ struct cr_panel *crp;
+ u8 dev_en;
+
+- crp = kzalloc(sizeof(crp), GFP_KERNEL);
++ crp = kzalloc(sizeof(*crp), GFP_KERNEL);
+ if (crp == NULL)
+ return -ENOMEM;
+
+diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
+index ab21495..083f603 100644
+--- a/drivers/video/macmodes.c
++++ b/drivers/video/macmodes.c
+@@ -369,9 +369,8 @@ EXPORT_SYMBOL(mac_map_monitor_sense);
+ *
+ */
+
+-int __devinit mac_find_mode(struct fb_var_screeninfo *var,
+- struct fb_info *info, const char *mode_option,
+- unsigned int default_bpp)
++int mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
++ const char *mode_option, unsigned int default_bpp)
+ {
+ const struct fb_videomode *db = NULL;
+ unsigned int dbsize = 0;
+diff --git a/drivers/video/macmodes.h b/drivers/video/macmodes.h
+index babeb81..b86ba08 100644
+--- a/drivers/video/macmodes.h
++++ b/drivers/video/macmodes.h
+@@ -55,10 +55,10 @@ extern int mac_vmode_to_var(int vmode, int cmode,
+ extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
+ int *cmode);
+ extern int mac_map_monitor_sense(int sense);
+-extern int __devinit mac_find_mode(struct fb_var_screeninfo *var,
+- struct fb_info *info,
+- const char *mode_option,
+- unsigned int default_bpp);
++extern int mac_find_mode(struct fb_var_screeninfo *var,
++ struct fb_info *info,
++ const char *mode_option,
++ unsigned int default_bpp);
+
+
+ /*
+diff --git a/fs/9p/conv.c b/fs/9p/conv.c
+index a3ed571..923d75c 100644
+--- a/fs/9p/conv.c
++++ b/fs/9p/conv.c
+@@ -742,6 +742,7 @@ struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
+ if (err) {
+ kfree(fc);
+ fc = ERR_PTR(err);
++ goto error;
+ }
+
+ if (buf_check_overflow(bufp)) {
+diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
+index 83e94fe..9c6877c 100644
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -902,8 +902,9 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
+ mutex_lock(&crypt_stat->cs_mutex);
+ if (S_ISDIR(dentry->d_inode->i_mode))
+ crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
+- else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
+- || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
++ else if (S_ISREG(dentry->d_inode->i_mode)
++ && (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
++ || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) {
+ struct vfsmount *lower_mnt;
+ struct file *lower_file = NULL;
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index b9ce241..fd10229 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -1445,7 +1445,7 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block,
+
+ static void
+ ext4_ext_put_in_cache(struct inode *inode, __u32 block,
+- __u32 len, __u32 start, int type)
++ __u32 len, ext4_fsblk_t start, int type)
+ {
+ struct ext4_ext_cache *cex;
+ BUG_ON(len == 0);
+diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
+index 1facfaf..a003d50 100644
+--- a/fs/jbd/commit.c
++++ b/fs/jbd/commit.c
+@@ -887,7 +887,8 @@ restart_loop:
+ journal->j_committing_transaction = NULL;
+ spin_unlock(&journal->j_state_lock);
+
+- if (commit_transaction->t_checkpoint_list == NULL) {
++ if (commit_transaction->t_checkpoint_list == NULL &&
++ commit_transaction->t_checkpoint_io_list == NULL) {
+ __journal_drop_transaction(journal, commit_transaction);
+ } else {
+ if (journal->j_checkpoint_transactions == NULL) {
+diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
+index 2856e11..c0f59d1 100644
+--- a/fs/jbd2/commit.c
++++ b/fs/jbd2/commit.c
+@@ -896,7 +896,8 @@ restart_loop:
+ journal->j_committing_transaction = NULL;
+ spin_unlock(&journal->j_state_lock);
+
+- if (commit_transaction->t_checkpoint_list == NULL) {
++ if (commit_transaction->t_checkpoint_list == NULL &&
++ commit_transaction->t_checkpoint_io_list == NULL) {
+ __jbd2_journal_drop_transaction(journal, commit_transaction);
+ } else {
+ if (journal->j_checkpoint_transactions == NULL) {
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 7e6aa24..9a68061 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1890,7 +1890,7 @@ nfsd_racache_init(int cache_size)
+ raparm_hash[i].pb_head = NULL;
+ spin_lock_init(&raparm_hash[i].pb_lock);
+ }
+- nperbucket = cache_size >> RAPARM_HASH_BITS;
++ nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE);
+ for (i = 0; i < cache_size - 1; i++) {
+ if (i % nperbucket == 0)
+ raparm_hash[j++].pb_head = raparml + i;
+diff --git a/fs/splice.c b/fs/splice.c
+index e7d7080..d3c6668 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -601,7 +601,7 @@ find_page:
+ ret = add_to_page_cache_lru(page, mapping, index,
+ GFP_KERNEL);
+ if (unlikely(ret))
+- goto out;
++ goto out_release;
+ }
+
+ ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
+@@ -657,8 +657,9 @@ find_page:
+ */
+ mark_page_accessed(page);
+ out:
+- page_cache_release(page);
+ unlock_page(page);
++out_release:
++ page_cache_release(page);
+ out_ret:
+ return ret;
+ }
+diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
+index b502c71..1f64ce5 100644
+--- a/fs/sysfs/file.c
++++ b/fs/sysfs/file.c
+@@ -283,6 +283,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
+ mutex_lock(&inode->i_mutex);
+ if (!(set = inode->i_private)) {
+ if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) {
++ mutex_unlock(&inode->i_mutex);
+ error = -ENOMEM;
+ goto Done;
+ } else {
+diff --git a/fs/timerfd.c b/fs/timerfd.c
+index af9eca5..61983f3 100644
+--- a/fs/timerfd.c
++++ b/fs/timerfd.c
+@@ -95,7 +95,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
+ {
+ struct timerfd_ctx *ctx = file->private_data;
+ ssize_t res;
+- u32 ticks = 0;
++ u64 ticks = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (count < sizeof(ticks))
+@@ -130,7 +130,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
+ * callback to avoid DoS attacks specifying a very
+ * short timer period.
+ */
+- ticks = (u32)
++ ticks = (u64)
+ hrtimer_forward(&ctx->tmr,
+ hrtimer_cb_get_time(&ctx->tmr),
+ ctx->tintv);
+@@ -140,7 +140,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
+ }
+ spin_unlock_irq(&ctx->wqh.lock);
+ if (ticks)
+- res = put_user(ticks, buf) ? -EFAULT: sizeof(ticks);
++ res = put_user(ticks, (u64 __user *) buf) ? -EFAULT: sizeof(ticks);
+ return res;
+ }
+
+diff --git a/include/linux/Kbuild b/include/linux/Kbuild
+index f317c27..b9c4d9e 100644
+--- a/include/linux/Kbuild
++++ b/include/linux/Kbuild
+@@ -137,6 +137,7 @@ header-y += radeonfb.h
+ header-y += raw.h
+ header-y += resource.h
+ header-y += rose.h
++header-y += serial_reg.h
+ header-y += smbno.h
+ header-y += snmp.h
+ header-y += sockios.h
+diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
+index 8e2042b..2eaa142 100644
+--- a/include/linux/ioprio.h
++++ b/include/linux/ioprio.h
+@@ -47,8 +47,10 @@ enum {
+ #define IOPRIO_NORM (4)
+ static inline int task_ioprio(struct task_struct *task)
+ {
+- WARN_ON(!ioprio_valid(task->ioprio));
+- return IOPRIO_PRIO_DATA(task->ioprio);
++ if (ioprio_valid(task->ioprio))
++ return IOPRIO_PRIO_DATA(task->ioprio);
++
++ return IOPRIO_NORM;
+ }
+
+ static inline int task_nice_ioprio(struct task_struct *task)
+diff --git a/include/linux/netfilter_ipv4/ipt_iprange.h b/include/linux/netfilter_ipv4/ipt_iprange.h
+index 34ab0fb..a92fefc 100644
+--- a/include/linux/netfilter_ipv4/ipt_iprange.h
++++ b/include/linux/netfilter_ipv4/ipt_iprange.h
+@@ -1,6 +1,8 @@
+ #ifndef _IPT_IPRANGE_H
+ #define _IPT_IPRANGE_H
+
++#include <linux/types.h>
++
+ #define IPRANGE_SRC 0x01 /* Match source IP address */
+ #define IPRANGE_DST 0x02 /* Match destination IP address */
+ #define IPRANGE_SRC_INV 0x10 /* Negate the condition */
+diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
+index 3c563f0..25aa575 100644
+--- a/include/net/bluetooth/rfcomm.h
++++ b/include/net/bluetooth/rfcomm.h
+@@ -323,6 +323,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc
+ #define RFCOMM_RELEASE_ONHUP 1
+ #define RFCOMM_HANGUP_NOW 2
+ #define RFCOMM_TTY_ATTACHED 3
++#define RFCOMM_TTY_RELEASED 4
+
+ struct rfcomm_dev_req {
+ s16 dev_id;
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 311f25a..4d56e16 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -577,7 +577,6 @@ static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ct
+ struct xfrm_dst
+ {
+ union {
+- struct xfrm_dst *next;
+ struct dst_entry dst;
+ struct rtable rt;
+ struct rt6_info rt6;
+diff --git a/ipc/shm.c b/ipc/shm.c
+index 0852f20..3bdcb9a 100644
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -716,7 +716,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
+ struct user_struct * user = current->user;
+ if (!is_file_hugepages(shp->shm_file)) {
+ err = shmem_lock(shp->shm_file, 1, user);
+- if (!err) {
++ if (!err && !(shp->shm_perm.mode & SHM_LOCKED)){
+ shp->shm_perm.mode |= SHM_LOCKED;
+ shp->mlock_user = user;
+ }
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 45490be..9b57f7e 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -2061,8 +2061,10 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val,
+ }
+ /*
+ * requeue parameter in 'utime' if cmd == FUTEX_REQUEUE.
++ * number of waiters to wake in 'utime' if cmd == FUTEX_WAKE_OP.
+ */
+- if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
++ if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
++ cmd == FUTEX_WAKE_OP)
+ val2 = (u32) (unsigned long) utime;
+
+ return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
+diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
+index 58f35e5..96f0417 100644
+--- a/kernel/lockdep_proc.c
++++ b/kernel/lockdep_proc.c
+@@ -339,7 +339,7 @@ static const struct file_operations proc_lockdep_stats_operations = {
+ .open = lockdep_stats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = single_release,
+ };
+
+ static int __init lockdep_proc_init(void)
+diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
+index 8bbcfb7..7ea87d9 100644
+--- a/kernel/time/timer_list.c
++++ b/kernel/time/timer_list.c
+@@ -267,7 +267,7 @@ static struct file_operations timer_list_fops = {
+ .open = timer_list_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = single_release,
+ };
+
+ static int __init init_timer_list_procfs(void)
+diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
+index 3216937..7bb561d 100644
+--- a/kernel/time/timer_stats.c
++++ b/kernel/time/timer_stats.c
+@@ -391,7 +391,7 @@ static struct file_operations tstats_fops = {
+ .read = seq_read,
+ .write = tstats_write,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = single_release,
+ };
+
+ void __init init_timer_stats(void)
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 3bebf73..3831f88 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -739,18 +739,17 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
+ if (cwq->thread == NULL)
+ return;
+
++ flush_cpu_workqueue(cwq);
+ /*
+- * If the caller is CPU_DEAD the single flush_cpu_workqueue()
+- * is not enough, a concurrent flush_workqueue() can insert a
+- * barrier after us.
++ * If the caller is CPU_DEAD and cwq->worklist was not empty,
++ * a concurrent flush_workqueue() can insert a barrier after us.
++ * However, in that case run_workqueue() won't return and check
++ * kthread_should_stop() until it flushes all work_struct's.
+ * When ->worklist becomes empty it is safe to exit because no
+ * more work_structs can be queued on this cwq: flush_workqueue
+ * checks list_empty(), and a "normal" queue_work() can't use
+ * a dead CPU.
+ */
+- while (flush_cpu_workqueue(cwq))
+- ;
+-
+ kthread_stop(cwq->thread);
+ cwq->thread = NULL;
+ }
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index a45d1f0..5fb38f1 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -101,13 +101,20 @@ static void free_huge_page(struct page *page)
+
+ static int alloc_fresh_huge_page(void)
+ {
+- static int nid = 0;
++ static int prev_nid;
+ struct page *page;
+- page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
+- HUGETLB_PAGE_ORDER);
+- nid = next_node(nid, node_online_map);
++ static DEFINE_SPINLOCK(nid_lock);
++ int nid;
++
++ spin_lock(&nid_lock);
++ nid = next_node(prev_nid, node_online_map);
+ if (nid == MAX_NUMNODES)
+ nid = first_node(node_online_map);
++ prev_nid = nid;
++ spin_unlock(&nid_lock);
++
++ page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
++ HUGETLB_PAGE_ORDER);
+ if (page) {
+ set_compound_page_dtor(page, free_huge_page);
+ spin_lock(&hugetlb_lock);
+diff --git a/mm/mlock.c b/mm/mlock.c
+index 4d3fea2..7b26560 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -244,9 +244,12 @@ int user_shm_lock(size_t size, struct user_struct *user)
+
+ locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ if (lock_limit == RLIM_INFINITY)
++ allowed = 1;
+ lock_limit >>= PAGE_SHIFT;
+ spin_lock(&shmlock_user_lock);
+- if (locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
++ if (!allowed &&
++ locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
+ goto out;
+ get_uid(user);
+ user->locked_shm += locked;
+diff --git a/mm/readahead.c b/mm/readahead.c
+index 9861e88..1448e53 100644
+--- a/mm/readahead.c
++++ b/mm/readahead.c
+@@ -21,8 +21,16 @@ void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
+ }
+ EXPORT_SYMBOL(default_unplug_io_fn);
+
++/*
++ * Convienent macros for min/max read-ahead pages.
++ * Note that MAX_RA_PAGES is rounded down, while MIN_RA_PAGES is rounded up.
++ * The latter is necessary for systems with large page size(i.e. 64k).
++ */
++#define MAX_RA_PAGES (VM_MAX_READAHEAD*1024 / PAGE_CACHE_SIZE)
++#define MIN_RA_PAGES DIV_ROUND_UP(VM_MIN_READAHEAD*1024, PAGE_CACHE_SIZE)
++
+ struct backing_dev_info default_backing_dev_info = {
+- .ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE,
++ .ra_pages = MAX_RA_PAGES,
+ .state = 0,
+ .capabilities = BDI_CAP_MAP_COPY,
+ .unplug_io_fn = default_unplug_io_fn,
+@@ -51,7 +59,7 @@ static inline unsigned long get_max_readahead(struct file_ra_state *ra)
+
+ static inline unsigned long get_min_readahead(struct file_ra_state *ra)
+ {
+- return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE;
++ return MIN_RA_PAGES;
+ }
+
+ static inline void reset_ahead_window(struct file_ra_state *ra)
+diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
+index b2b1cce..23ba61a 100644
+--- a/net/bluetooth/rfcomm/tty.c
++++ b/net/bluetooth/rfcomm/tty.c
+@@ -95,6 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
+
+ BT_DBG("dev %p dlc %p", dev, dlc);
+
++ write_lock_bh(&rfcomm_dev_lock);
++ list_del_init(&dev->list);
++ write_unlock_bh(&rfcomm_dev_lock);
++
+ rfcomm_dlc_lock(dlc);
+ /* Detach DLC if it's owned by this dev */
+ if (dlc->owner == dev)
+@@ -156,8 +160,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
+ read_lock(&rfcomm_dev_lock);
+
+ dev = __rfcomm_dev_get(id);
+- if (dev)
+- rfcomm_dev_hold(dev);
++
++ if (dev) {
++ if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
++ dev = NULL;
++ else
++ rfcomm_dev_hold(dev);
++ }
+
+ read_unlock(&rfcomm_dev_lock);
+
+@@ -265,6 +274,12 @@ out:
+
+ dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
+
++ if (IS_ERR(dev->tty_dev)) {
++ list_del(&dev->list);
++ kfree(dev);
++ return PTR_ERR(dev->tty_dev);
++ }
++
+ return dev->id;
+ }
+
+@@ -272,10 +287,7 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
+ {
+ BT_DBG("dev %p", dev);
+
+- write_lock_bh(&rfcomm_dev_lock);
+- list_del_init(&dev->list);
+- write_unlock_bh(&rfcomm_dev_lock);
+-
++ set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
+ rfcomm_dev_put(dev);
+ }
+
+@@ -329,7 +341,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
+ if (copy_from_user(&req, arg, sizeof(req)))
+ return -EFAULT;
+
+- BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
++ BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
+
+ if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
+ return -EPERM;
+@@ -370,7 +382,7 @@ static int rfcomm_release_dev(void __user *arg)
+ if (copy_from_user(&req, arg, sizeof(req)))
+ return -EFAULT;
+
+- BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
++ BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
+
+ if (!(dev = rfcomm_dev_get(req.dev_id)))
+ return -ENODEV;
+@@ -383,6 +395,10 @@ static int rfcomm_release_dev(void __user *arg)
+ if (req.flags & (1 << RFCOMM_HANGUP_NOW))
+ rfcomm_dlc_close(dev->dlc, 0);
+
++ /* Shut down TTY synchronously before freeing rfcomm_dev */
++ if (dev->tty)
++ tty_vhangup(dev->tty);
++
+ rfcomm_dev_del(dev);
+ rfcomm_dev_put(dev);
+ return 0;
+@@ -415,6 +431,8 @@ static int rfcomm_get_dev_list(void __user *arg)
+
+ list_for_each(p, &rfcomm_dev_list) {
+ struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
++ if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
++ continue;
+ (di + n)->id = dev->id;
+ (di + n)->flags = dev->flags;
+ (di + n)->state = dev->dlc->state;
+diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
+index 031bfa4..984e9c6 100644
+--- a/net/bridge/netfilter/ebt_log.c
++++ b/net/bridge/netfilter/ebt_log.c
+@@ -196,10 +196,8 @@ static int __init ebt_log_init(void)
+ ret = ebt_register_watcher(&log);
+ if (ret < 0)
+ return ret;
+- ret = nf_log_register(PF_BRIDGE, &ebt_log_logger);
+- if (ret < 0 && ret != -EEXIST)
+- ebt_unregister_watcher(&log);
+- return ret;
++ nf_log_register(PF_BRIDGE, &ebt_log_logger);
++ return 0;
+ }
+
+ static void __exit ebt_log_fini(void)
+diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
+index 9411db6..6fec352 100644
+--- a/net/bridge/netfilter/ebt_ulog.c
++++ b/net/bridge/netfilter/ebt_ulog.c
+@@ -308,12 +308,8 @@ static int __init ebt_ulog_init(void)
+ else if ((ret = ebt_register_watcher(&ulog)))
+ sock_release(ebtulognl->sk_socket);
+
+- if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) {
+- printk(KERN_WARNING "ebt_ulog: not logging via ulog "
+- "since somebody else already registered for PF_BRIDGE\n");
+- /* we cannot make module load fail here, since otherwise
+- * ebtables userspace would abort */
+- }
++ if (ret == 0)
++ nf_log_register(PF_BRIDGE, &ebt_ulog_logger);
+
+ return ret;
+ }
+diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
+index 17daf4c..590a767 100644
+--- a/net/core/gen_estimator.c
++++ b/net/core/gen_estimator.c
+@@ -79,27 +79,27 @@
+
+ struct gen_estimator
+ {
+- struct gen_estimator *next;
++ struct list_head list;
+ struct gnet_stats_basic *bstats;
+ struct gnet_stats_rate_est *rate_est;
+ spinlock_t *stats_lock;
+- unsigned interval;
+ int ewma_log;
+ u64 last_bytes;
+ u32 last_packets;
+ u32 avpps;
+ u32 avbps;
++ struct rcu_head e_rcu;
+ };
+
+ struct gen_estimator_head
+ {
+ struct timer_list timer;
+- struct gen_estimator *list;
++ struct list_head list;
+ };
+
+ static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
+
+-/* Estimator array lock */
++/* Protects against NULL dereference */
+ static DEFINE_RWLOCK(est_lock);
+
+ static void est_timer(unsigned long arg)
+@@ -107,13 +107,17 @@ static void est_timer(unsigned long arg)
+ int idx = (int)arg;
+ struct gen_estimator *e;
+
+- read_lock(&est_lock);
+- for (e = elist[idx].list; e; e = e->next) {
++ rcu_read_lock();
++ list_for_each_entry_rcu(e, &elist[idx].list, list) {
+ u64 nbytes;
+ u32 npackets;
+ u32 rate;
+
+ spin_lock(e->stats_lock);
++ read_lock(&est_lock);
++ if (e->bstats == NULL)
++ goto skip;
++
+ nbytes = e->bstats->bytes;
+ npackets = e->bstats->packets;
+ rate = (nbytes - e->last_bytes)<<(7 - idx);
+@@ -125,11 +129,14 @@ static void est_timer(unsigned long arg)
+ e->last_packets = npackets;
+ e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log;
+ e->rate_est->pps = (e->avpps+0x1FF)>>10;
++skip:
++ read_unlock(&est_lock);
+ spin_unlock(e->stats_lock);
+ }
+
+- mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+- read_unlock(&est_lock);
++ if (!list_empty(&elist[idx].list))
++ mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
++ rcu_read_unlock();
+ }
+
+ /**
+@@ -146,12 +153,17 @@ static void est_timer(unsigned long arg)
+ * &rate_est with the statistics lock grabed during this period.
+ *
+ * Returns 0 on success or a negative error code.
++ *
++ * NOTE: Called under rtnl_mutex
+ */
+ int gen_new_estimator(struct gnet_stats_basic *bstats,
+- struct gnet_stats_rate_est *rate_est, spinlock_t *stats_lock, struct rtattr *opt)
++ struct gnet_stats_rate_est *rate_est,
++ spinlock_t *stats_lock,
++ struct rtattr *opt)
+ {
+ struct gen_estimator *est;
+ struct gnet_estimator *parm = RTA_DATA(opt);
++ int idx;
+
+ if (RTA_PAYLOAD(opt) < sizeof(*parm))
+ return -EINVAL;
+@@ -163,7 +175,7 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
+ if (est == NULL)
+ return -ENOBUFS;
+
+- est->interval = parm->interval + 2;
++ idx = parm->interval + 2;
+ est->bstats = bstats;
+ est->rate_est = rate_est;
+ est->stats_lock = stats_lock;
+@@ -173,20 +185,25 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
+ est->last_packets = bstats->packets;
+ est->avpps = rate_est->pps<<10;
+
+- est->next = elist[est->interval].list;
+- if (est->next == NULL) {
+- init_timer(&elist[est->interval].timer);
+- elist[est->interval].timer.data = est->interval;
+- elist[est->interval].timer.expires = jiffies + ((HZ<<est->interval)/4);
+- elist[est->interval].timer.function = est_timer;
+- add_timer(&elist[est->interval].timer);
++ if (!elist[idx].timer.function) {
++ INIT_LIST_HEAD(&elist[idx].list);
++ setup_timer(&elist[idx].timer, est_timer, idx);
+ }
+- write_lock_bh(&est_lock);
+- elist[est->interval].list = est;
+- write_unlock_bh(&est_lock);
++
++ if (list_empty(&elist[idx].list))
++ mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
++
++ list_add_rcu(&est->list, &elist[idx].list);
+ return 0;
+ }
+
++static void __gen_kill_estimator(struct rcu_head *head)
++{
++ struct gen_estimator *e = container_of(head,
++ struct gen_estimator, e_rcu);
++ kfree(e);
++}
++
+ /**
+ * gen_kill_estimator - remove a rate estimator
+ * @bstats: basic statistics
+@@ -194,31 +211,32 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
+ *
+ * Removes the rate estimator specified by &bstats and &rate_est
+ * and deletes the timer.
++ *
++ * NOTE: Called under rtnl_mutex
+ */
+ void gen_kill_estimator(struct gnet_stats_basic *bstats,
+ struct gnet_stats_rate_est *rate_est)
+ {
+ int idx;
+- struct gen_estimator *est, **pest;
++ struct gen_estimator *e, *n;
+
+ for (idx=0; idx <= EST_MAX_INTERVAL; idx++) {
+- int killed = 0;
+- pest = &elist[idx].list;
+- while ((est=*pest) != NULL) {
+- if (est->rate_est != rate_est || est->bstats != bstats) {
+- pest = &est->next;
++
++ /* Skip non initialized indexes */
++ if (!elist[idx].timer.function)
++ continue;
++
++ list_for_each_entry_safe(e, n, &elist[idx].list, list) {
++ if (e->rate_est != rate_est || e->bstats != bstats)
+ continue;
+- }
+
+ write_lock_bh(&est_lock);
+- *pest = est->next;
++ e->bstats = NULL;
+ write_unlock_bh(&est_lock);
+
+- kfree(est);
+- killed++;
++ list_del_rcu(&e->list);
++ call_rcu(&e->e_rcu, __gen_kill_estimator);
+ }
+- if (killed && elist[idx].list == NULL)
+- del_timer(&elist[idx].timer);
+ }
+ }
+
+diff --git a/net/core/netpoll.c b/net/core/netpoll.c
+index a0efdd7..5df8cf4 100644
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -781,7 +781,6 @@ void netpoll_cleanup(struct netpoll *np)
+ spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+ }
+
+- np->dev->npinfo = NULL;
+ if (atomic_dec_and_test(&npinfo->refcnt)) {
+ skb_queue_purge(&npinfo->arp_tx);
+ skb_queue_purge(&npinfo->txq);
+@@ -794,6 +793,7 @@ void netpoll_cleanup(struct netpoll *np)
+ kfree_skb(skb);
+ }
+ kfree(npinfo);
++ np->dev->npinfo = NULL;
+ }
+ }
+
+diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
+index cc8110b..afb6c66 100644
+--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
++++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
+@@ -271,8 +271,11 @@ ieee80211softmac_assoc_work(struct work_struct *work)
+ */
+ dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
+ ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
+- if (ieee80211softmac_start_scan(mac))
++ if (ieee80211softmac_start_scan(mac)) {
+ dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
++ mac->associnfo.associating = 0;
++ mac->associnfo.associated = 0;
++ }
+ goto out;
+ } else {
+ mac->associnfo.associating = 0;
+diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
+index a42c5cd..361be2b 100644
+--- a/net/ipv4/netfilter/ipt_LOG.c
++++ b/net/ipv4/netfilter/ipt_LOG.c
+@@ -477,10 +477,8 @@ static int __init ipt_log_init(void)
+ ret = xt_register_target(&ipt_log_reg);
+ if (ret < 0)
+ return ret;
+- ret = nf_log_register(PF_INET, &ipt_log_logger);
+- if (ret < 0 && ret != -EEXIST)
+- xt_unregister_target(&ipt_log_reg);
+- return ret;
++ nf_log_register(PF_INET, &ipt_log_logger);
++ return 0;
+ }
+
+ static void __exit ipt_log_fini(void)
+diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+index f4fc657..474b4ce 100644
+--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
++++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+@@ -189,25 +189,13 @@ icmp_error_message(struct sk_buff *skb,
+
+ h = nf_conntrack_find_get(&innertuple, NULL);
+ if (!h) {
+- /* Locally generated ICMPs will match inverted if they
+- haven't been SNAT'ed yet */
+- /* FIXME: NAT code has to handle half-done double NAT --RR */
+- if (hooknum == NF_IP_LOCAL_OUT)
+- h = nf_conntrack_find_get(&origtuple, NULL);
+-
+- if (!h) {
+- DEBUGP("icmp_error_message: no match\n");
+- return -NF_ACCEPT;
+- }
+-
+- /* Reverse direction from that found */
+- if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
+- *ctinfo += IP_CT_IS_REPLY;
+- } else {
+- if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
+- *ctinfo += IP_CT_IS_REPLY;
++ DEBUGP("icmp_error_message: no match\n");
++ return -NF_ACCEPT;
+ }
+
++ if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
++ *ctinfo += IP_CT_IS_REPLY;
++
+ /* Update skb to refer to this connection */
+ skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
+ skb->nfctinfo = *ctinfo;
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 69f9f1e..4e5884a 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -1398,7 +1398,9 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
+ * waiting for the first ACK and did not get it)...
+ */
+ if ((tp->frto_counter == 1) && !(flag&FLAG_DATA_ACKED)) {
+- tp->retrans_out += tcp_skb_pcount(skb);
++ /* For some reason this R-bit might get cleared? */
++ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
++ tp->retrans_out += tcp_skb_pcount(skb);
+ /* ...enter this if branch just for the first segment */
+ flag |= FLAG_DATA_ACKED;
+ } else {
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index f96ed76..2cc3728 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -2472,6 +2472,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
+ write_unlock_bh(&idev->lock);
+
+ __ipv6_ifa_notify(RTM_DELADDR, ifa);
++ atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
+ in6_ifa_put(ifa);
+
+ write_lock_bh(&idev->lock);
+diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
+index 9b81264..2f49578 100644
+--- a/net/ipv6/anycast.c
++++ b/net/ipv6/anycast.c
+@@ -66,6 +66,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev)
+ break;
+ }
+ read_unlock_bh(&idev->lock);
++ in6_dev_put(idev);
+ }
+ rcu_read_unlock();
+ return onlink;
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index e9bcce9..c956037 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -604,7 +604,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
+
+ read_lock(&raw_v6_lock);
+ if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
+- while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr,
++ while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr,
+ IP6CB(skb)->iif))) {
+ rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
+ sk = sk_next(sk);
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index a0902fb..31f9252 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -962,8 +962,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
+ dsfield = ipv4_get_dsfield(iph);
+
+ if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
+- fl.fl6_flowlabel |= ntohl(((__u32)iph->tos << IPV6_TCLASS_SHIFT)
+- & IPV6_TCLASS_MASK);
++ fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
++ & IPV6_TCLASS_MASK;
+
+ err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu);
+ if (err != 0) {
+diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
+index 5bb9cd3..a7a2517 100644
+--- a/net/ipv6/netfilter/ip6t_LOG.c
++++ b/net/ipv6/netfilter/ip6t_LOG.c
+@@ -490,10 +490,8 @@ static int __init ip6t_log_init(void)
+ ret = xt_register_target(&ip6t_log_reg);
+ if (ret < 0)
+ return ret;
+- ret = nf_log_register(PF_INET6, &ip6t_logger);
+- if (ret < 0 && ret != -EEXIST)
+- xt_unregister_target(&ip6t_log_reg);
+- return ret;
++ nf_log_register(PF_INET6, &ip6t_logger);
++ return 0;
+ }
+
+ static void __exit ip6t_log_fini(void)
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 193d9d6..17bbdc3 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -644,6 +644,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
+ if (tp->md5sig_info->entries6 == 0) {
+ kfree(tp->md5sig_info->keys6);
+ tp->md5sig_info->keys6 = NULL;
++ tp->md5sig_info->alloced6 = 0;
+
+ tcp_free_md5sig_pool();
+
+diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
+index e5c840c..230e35c 100644
+--- a/net/rfkill/rfkill-input.c
++++ b/net/rfkill/rfkill-input.c
+@@ -55,7 +55,7 @@ static void rfkill_task_handler(struct work_struct *work)
+
+ static void rfkill_schedule_toggle(struct rfkill_task *task)
+ {
+- unsigned int flags;
++ unsigned long flags;
+
+ spin_lock_irqsave(&task->lock, flags);
+
+diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
+index bec600a..7a6b0b7 100644
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -290,11 +290,7 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
+
+ wd->qdisc->flags &= ~TCQ_F_THROTTLED;
+ smp_wmb();
+- if (spin_trylock(&dev->queue_lock)) {
+- qdisc_run(dev);
+- spin_unlock(&dev->queue_lock);
+- } else
+- netif_schedule(dev);
++ netif_schedule(dev);
+
+ return HRTIMER_NORESTART;
+ }
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 2c29394..2164b51 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -875,6 +875,10 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
+ dev = dev_get_by_index(addr->v6.sin6_scope_id);
+ if (!dev)
+ return 0;
++ if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
++ dev_put(dev);
++ return 0;
++ }
+ dev_put(dev);
+ }
+ af = opt->pf->af;
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 099a983..805e725 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -760,11 +760,12 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
+ new->h.flavour = &svcauthops_gss;
+ new->pseudoflavor = pseudoflavor;
+
++ stat = 0;
+ test = auth_domain_lookup(name, &new->h);
+- if (test != &new->h) { /* XXX Duplicate registration? */
+- auth_domain_put(&new->h);
+- /* dangling ref-count... */
+- goto out;
++ if (test != &new->h) { /* Duplicate registration */
++ auth_domain_put(test);
++ kfree(new->h.name);
++ goto out_free_dom;
+ }
+ return 0;
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 157bfbd..b48f06f 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -2141,7 +2141,7 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
+ if (last == first)
+ break;
+
+- last = last->u.next;
++ last = (struct xfrm_dst *)last->u.dst.next;
+ last->child_mtu_cached = mtu;
+ }
+
Modified: dists/sid/linux-2.6/debian/patches/series/4
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/4 (original)
+++ dists/sid/linux-2.6/debian/patches/series/4 Fri Aug 10 06:41:20 2007
@@ -28,3 +28,4 @@
+ bugfix/hppa/use-generic-compat_sys_getdents.patch
+ bugfix/powerpc/i8042-pegasos.patch
+ bugfix/sparc/sun4u-pci-config-space.patch
++ bugfix/2.6.22.2
More information about the Kernel-svn-changes
mailing list