[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