[kernel] r13863 - in dists/sid/linux-2.6/debian: . patches/bugfix/all/stable patches/series

Bastian Blank waldi at alioth.debian.org
Fri Jul 3 15:06:05 UTC 2009


Author: waldi
Date: Fri Jul  3 15:05:53 2009
New Revision: 13863

Log:
Add stable release 2.6.30.1.

* debian/changelog: Update.
* debian/patches/bugfix/all/stable/2.6.30.1.patch: Add.
* debian/patches/series/2: Add new patch.

Added:
   dists/sid/linux-2.6/debian/patches/bugfix/all/stable/2.6.30.1.patch
   dists/sid/linux-2.6/debian/patches/series/2
Modified:
   dists/sid/linux-2.6/debian/changelog

Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	Thu Jul  2 09:26:42 2009	(r13862)
+++ dists/sid/linux-2.6/debian/changelog	Fri Jul  3 15:05:53 2009	(r13863)
@@ -1,7 +1,123 @@
 linux-2.6 (2.6.30-2) UNRELEASED; urgency=low
 
+  [ dann frazier ]
   * [powerpc] Use generic rtc (closes: #535354)
 
+  [ Bastian Blank ]
+  * Add stable release 2.6.30.1:
+    - firmware_map: fix hang with x86/32bit
+    - fs: remove incorrect I_NEW warnings
+    - PCI: disable ASPM on VIA root-port-under-bridge configurations
+    - KVM: Add VT-x machine check support v4
+    - KVM: Disable large pages on misaligned memory slots
+    - KVM: Prevent overflow in largepages calculation
+    - KVM: x86: check for cr3 validity in ioctl_set_sregs
+    - KVM: VMX: Handle vmx instruction vmexits
+    - KVM: protect concurrent make_all_cpus_request
+    - KVM: Fix dirty bit tracking for slots with large pages
+    - IMA: use current_cred() instead of current->cred
+    - IMA: Handle dentry_open failures
+    - IMA: open all files O_LARGEFILE
+    - e1000e: stop unnecessary polling when using msi-x
+    - pegasus usb-net: Fix endianness bugs
+    - ipv4: fix NULL pointer + success return in route lookup path
+    - ipv4 routing: Ensure that route cache entries are usable and reclaimable
+      with caching is off
+    - sky2: don't look for VPD size
+    - tun: Fix unregister race
+    - via-velocity: Fix velocity driver unmapping incorrect size.
+    - x25: Fix sleep from timer on socket destroy.
+    - bonding: fix multiple module load problem
+    - dma-debug: change hash_bucket_find from first-fit to best-fit
+    - char: moxa, prevent opening unavailable ports
+    - serial: refactor ASYNC_ flags
+    - rocket: fix test_bit parameters
+    - epca: fix test_bit parameters
+    - x86: Detect use of extended APIC ID for AMD CPUs
+    - USB: usbtmc: fix switch statment
+    - DVB: lgdt3305: fix 64bit division in function lgdt3305_set_if
+    - V4L: ivtv/cx18: fix regression: class controls are no longer seen
+    - V4L: pvrusb2: Fix hardware scaling when used with cx25840
+    - V4L: pvrusb2: Re-fix hardware scaling on video standard change
+    - V4L: i2c modules must be linked before the v4l2 drivers
+    - sym53c8xx: ratelimit parity errors
+    - ISDN: Fix DMA alloc for hfcpci
+    - jfs: fix regression preventing coalescing of extents
+    - spi: takes size of a pointer to determine the size of the pointed-to type
+    - serial: bfin_5xx: add missing spin_lock init
+    - x86: memtest: remove 64-bit division
+    - x86: Fix UV BAU activation descriptor init
+    - x86, UV: Fix macros for multiple coherency domains
+    - x86: enable GART-IOMMU only after setting up protection methods
+    - x86: move rdtsc_barrier() into the TSC vread method
+    - x86: Fix uv bau sending buffer initialization
+    - x86: Add quirk for reboot stalls on a Dell Optiplex 360
+    - x86: handle initrd that extends into unusable memory
+    - ALSA: ca0106 - Add missing registrations of vmaster controls
+    - ALSA: intel8x0 - Fix PCM position craziness
+    - ALSA: hda - Get back Input Source for ALC262 toshiba-s06 model
+    - ALSA: hda - Add quirk for Sony VAIO Z21MN
+    - ALSA: cmi8330: fix MPU-401 PnP init copy&paste bug
+    - x86: hpet: Mark per cpu interrupts IRQF_TIMER to prevent resume failure
+    - ARM: 5545/2: add flush_kernel_dcache_page() for ARM
+    - IB/mlx4: Add strong ordering to local inval and fast reg work requests
+    - epoll: fix nested calls support
+    - lockdep: Select frame pointers on x86
+    - ASoC: Remove odd bit clock ratios for WM8903
+    - ramfs: ignore unknown mount options
+    - mac80211: fix minstrel single-rate memory corruption
+    - cfg80211: fix for duplicate userspace replies
+    - cfg80211: cleanup return calls on nl80211_set_reg()
+    - cfg80211: return immediately if num reg rules > NL80211_MAX_SUPP_REG_RULES
+    - cfg80211: fix in nl80211_set_reg()
+    - ath9k: Fix bug when using a card with a busted EEPROM
+    - ath9k: Fix bug in calibration initialization
+    - ath9k: Fix bug in determining calibration support
+    - ath9k: Fix bug in checking HT flag
+    - ath9k: Fix bug in scan termination
+    - ath9k: Fix memleak on TX DMA failure
+    - ath9k: Initialize ANI timers
+    - ath9k: Fix PCI FATAL interrupts by restoring RETRY_TIMEOUT disabling
+    - crypto: aes-ni - Fix cbc mode IV saving
+    - md/raid5: add missing call to schedule() after prepare_to_wait()
+    - tracing/urgent: fix unbalanced ftrace_start_up
+    - cifs: fix fh_mutex locking in cifs_reopen_file
+    - vt_ioctl: fix lock imbalance
+    - x86: Fix non-lazy GS handling in sys_vm86()
+    - x86: Set cpu_llc_id on AMD CPUs
+    - usb-serial: replace shutdown with disconnect, release
+    - pcmcia/cm4000: fix lock imbalance
+    - n_r3964: fix lock imbalance
+    - parport_pc: set properly the dma_mask for parport_pc device
+    - parport_pc: after superio probing restore original register values
+    - mv643xx_eth: fix unicast filter programming in promiscuous mode
+    - ath5k: avoid PCI FATAL interrupts by restoring RETRY_TIMEOUT disabling
+    - sound: seq_midi_event: fix decoding of (N)RPN events
+    - PCI PM: Fix handling of devices without PM support by pci_target_state()
+    - PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3
+    - qla2xxx: Correct (again) overflow during dump-processing on large-memory
+      ISP23xx parts.
+    - mm: fix handling of pagesets for downed cpus
+    - dm mpath: validate hw_handler argument count
+    - dm mpath: validate table argument count
+    - dm: sysfs skip output when device is being destroyed
+    - dm mpath: flush keventd queue in destructor
+    - dm exception store: fix exstore lookup to be case insensitive
+    - dm exception store: really fix type lookup
+    - dm: use i_size_read
+    - vmscan: properly account for the number of page cache pages zone_reclaim()
+      can reclaim
+    - vmscan: count the number of times zone_reclaim() scans and fails
+    - lib/genalloc.c: remove unmatched write_lock() in gen_pool_destroy
+    - CONFIG_FILE_LOCKING should not depend on CONFIG_BLOCK
+    - serial: bfin_5xx: fix building as module when early printk is enabled
+    - ocfs2: Fix ocfs2_osb_dump()
+    - ide-cd: prevent null pointer deref via cdrom_newpc_intr
+    - drm/i915: correct suspend/resume ordering
+    - KVM: x86: silence preempt warning on kvm_write_guest_time
+    - xfs: fix freeing memory in xfs_getbmap()
+    - bsdacct: fix access to invalid filp in acct_on()
+
  -- dann frazier <dannf at debian.org>  Wed, 01 Jul 2009 16:49:20 -0600
 
 linux-2.6 (2.6.30-1) unstable; urgency=low

Added: dists/sid/linux-2.6/debian/patches/bugfix/all/stable/2.6.30.1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/stable/2.6.30.1.patch	Fri Jul  3 15:05:53 2009	(r13863)
@@ -0,0 +1,5247 @@
+diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
+index c302ddf..5236573 100644
+--- a/Documentation/sysctl/vm.txt
++++ b/Documentation/sysctl/vm.txt
+@@ -314,10 +314,14 @@ min_unmapped_ratio:
+ 
+ This is available only on NUMA kernels.
+ 
+-A percentage of the total pages in each zone.  Zone reclaim will only
+-occur if more than this percentage of pages are file backed and unmapped.
+-This is to insure that a minimal amount of local pages is still available for
+-file I/O even if the node is overallocated.
++This is a percentage of the total pages in each zone. Zone reclaim will
++only occur if more than this percentage of pages are in a state that
++zone_reclaim_mode allows to be reclaimed.
++
++If zone_reclaim_mode has the value 4 OR'd, then the percentage is compared
++against all file-backed unmapped pages including swapcache pages and tmpfs
++files. Otherwise, only unmapped pages backed by normal files but not tmpfs
++files and similar are considered.
+ 
+ The default is 1 percent.
+ 
+diff --git a/Makefile b/Makefile
+index 03373bb..f8a0893 100644
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index bb7d695..1a711ea 100644
+--- a/arch/arm/include/asm/cacheflush.h
++++ b/arch/arm/include/asm/cacheflush.h
+@@ -429,6 +429,14 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
+ 		__flush_anon_page(vma, page, vmaddr);
+ }
+ 
++#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
++static inline void flush_kernel_dcache_page(struct page *page)
++{
++	/* highmem pages are always flushed upon kunmap already */
++	if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page))
++		__cpuc_flush_dcache_page(page_address(page));
++}
++
+ #define flush_dcache_mmap_lock(mapping) \
+ 	spin_lock_irq(&(mapping)->tree_lock)
+ #define flush_dcache_mmap_unlock(mapping) \
+diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
+index caba996..eb0566e 100644
+--- a/arch/x86/crypto/aesni-intel_asm.S
++++ b/arch/x86/crypto/aesni-intel_asm.S
+@@ -845,7 +845,7 @@ ENTRY(aesni_cbc_enc)
+  */
+ ENTRY(aesni_cbc_dec)
+ 	cmp $16, LEN
+-	jb .Lcbc_dec_ret
++	jb .Lcbc_dec_just_ret
+ 	mov 480(KEYP), KLEN
+ 	add $240, KEYP
+ 	movups (IVP), IV
+@@ -891,6 +891,7 @@ ENTRY(aesni_cbc_dec)
+ 	add $16, OUTP
+ 	cmp $16, LEN
+ 	jge .Lcbc_dec_loop1
+-	movups IV, (IVP)
+ .Lcbc_dec_ret:
++	movups IV, (IVP)
++.Lcbc_dec_just_ret:
+ 	ret
+diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
+index 42f2f83..9b2c049 100644
+--- a/arch/x86/include/asm/apic.h
++++ b/arch/x86/include/asm/apic.h
+@@ -410,7 +410,7 @@ static inline unsigned default_get_apic_id(unsigned long x)
+ {
+ 	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
+ 
+-	if (APIC_XAPIC(ver))
++	if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
+ 		return (x >> 24) & 0xFF;
+ 	else
+ 		return (x >> 24) & 0x0F;
+diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
+index bb83b1c..78dee4f 100644
+--- a/arch/x86/include/asm/cpufeature.h
++++ b/arch/x86/include/asm/cpufeature.h
+@@ -94,6 +94,7 @@
+ #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */
+ #define X86_FEATURE_NONSTOP_TSC	(3*32+24) /* TSC does not stop in C states */
+ #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */
++#define X86_FEATURE_EXTD_APICID	(3*32+26) /* has extended APICID (8 bits) */
+ 
+ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+ #define X86_FEATURE_XMM3	(4*32+ 0) /* "pni" SSE-3 */
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index f0faf58..a93d1cc 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -371,6 +371,8 @@ struct kvm_vcpu_arch {
+ 	unsigned long dr6;
+ 	unsigned long dr7;
+ 	unsigned long eff_db[KVM_NR_DB_REGS];
++
++	u32 exit_reason;
+ };
+ 
+ struct kvm_mem_alias {
+diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
+index 4f8c199..5c70378 100644
+--- a/arch/x86/include/asm/mce.h
++++ b/arch/x86/include/asm/mce.h
+@@ -153,5 +153,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c);
+ 
+ extern void (*mce_threshold_vector)(void);
+ 
++extern void (*machine_check_vector)(struct pt_regs *, long error_code);
++
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_X86_MCE_H */
+diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h
+index 9b0e61b..bddd44f 100644
+--- a/arch/x86/include/asm/uv/uv_bau.h
++++ b/arch/x86/include/asm/uv/uv_bau.h
+@@ -37,7 +37,7 @@
+ #define UV_CPUS_PER_ACT_STATUS		32
+ #define UV_ACT_STATUS_MASK		0x3
+ #define UV_ACT_STATUS_SIZE		2
+-#define UV_ACTIVATION_DESCRIPTOR_SIZE	32
++#define UV_ADP_SIZE			32
+ #define UV_DISTRIBUTION_SIZE		256
+ #define UV_SW_ACK_NPENDING		8
+ #define UV_NET_ENDPOINT_INTD		0x38
+diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
+index d3a98ea..341070f 100644
+--- a/arch/x86/include/asm/uv/uv_hub.h
++++ b/arch/x86/include/asm/uv/uv_hub.h
+@@ -133,6 +133,7 @@ struct uv_scir_s {
+ struct uv_hub_info_s {
+ 	unsigned long		global_mmr_base;
+ 	unsigned long		gpa_mask;
++	unsigned int		gnode_extra;
+ 	unsigned long		gnode_upper;
+ 	unsigned long		lowmem_remap_top;
+ 	unsigned long		lowmem_remap_base;
+@@ -159,7 +160,8 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
+  * 		p -  PNODE (local part of nsids, right shifted 1)
+  */
+ #define UV_NASID_TO_PNODE(n)		(((n) >> 1) & uv_hub_info->pnode_mask)
+-#define UV_PNODE_TO_NASID(p)		(((p) << 1) | uv_hub_info->gnode_upper)
++#define UV_PNODE_TO_GNODE(p)		((p) |uv_hub_info->gnode_extra)
++#define UV_PNODE_TO_NASID(p)		(UV_PNODE_TO_GNODE(p) << 1)
+ 
+ #define UV_LOCAL_MMR_BASE		0xf4000000UL
+ #define UV_GLOBAL_MMR32_BASE		0xf8000000UL
+@@ -173,7 +175,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
+ #define UV_GLOBAL_MMR32_PNODE_BITS(p)	((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT))
+ 
+ #define UV_GLOBAL_MMR64_PNODE_BITS(p)					\
+-	((unsigned long)(p) << UV_GLOBAL_MMR64_PNODE_SHIFT)
++	((unsigned long)(UV_PNODE_TO_GNODE(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
+ 
+ #define UV_APIC_PNODE_SHIFT	6
+ 
+diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
+index 498f944..11be5ad 100644
+--- a/arch/x86/include/asm/vmx.h
++++ b/arch/x86/include/asm/vmx.h
+@@ -247,6 +247,7 @@ enum vmcs_field {
+ #define EXIT_REASON_MSR_READ            31
+ #define EXIT_REASON_MSR_WRITE           32
+ #define EXIT_REASON_MWAIT_INSTRUCTION   36
++#define EXIT_REASON_MCE_DURING_VMENTRY	 41
+ #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
+ #define EXIT_REASON_APIC_ACCESS         44
+ #define EXIT_REASON_EPT_VIOLATION       48
+diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
+index 2bda693..39f2af4 100644
+--- a/arch/x86/kernel/apic/x2apic_uv_x.c
++++ b/arch/x86/kernel/apic/x2apic_uv_x.c
+@@ -562,7 +562,7 @@ void __init uv_system_init(void)
+ 	union uvh_node_id_u node_id;
+ 	unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
+ 	int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val;
+-	int max_pnode = 0;
++	int gnode_extra, max_pnode = 0;
+ 	unsigned long mmr_base, present, paddr;
+ 	unsigned short pnode_mask;
+ 
+@@ -574,6 +574,13 @@ void __init uv_system_init(void)
+ 	mmr_base =
+ 	    uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
+ 	    ~UV_MMR_ENABLE;
++	pnode_mask = (1 << n_val) - 1;
++	node_id.v = uv_read_local_mmr(UVH_NODE_ID);
++	gnode_extra = (node_id.s.node_id & ~((1 << n_val) - 1)) >> 1;
++	gnode_upper = ((unsigned long)gnode_extra  << m_val);
++	printk(KERN_DEBUG "UV: N %d, M %d, gnode_upper 0x%lx, gnode_extra 0x%x\n",
++			n_val, m_val, gnode_upper, gnode_extra);
++
+ 	printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base);
+ 
+ 	for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++)
+@@ -607,11 +614,6 @@ void __init uv_system_init(void)
+ 		}
+ 	}
+ 
+-	pnode_mask = (1 << n_val) - 1;
+-	node_id.v = uv_read_local_mmr(UVH_NODE_ID);
+-	gnode_upper = (((unsigned long)node_id.s.node_id) &
+-		       ~((1 << n_val) - 1)) << m_val;
+-
+ 	uv_bios_init();
+ 	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
+ 			    &sn_coherency_id, &sn_region_size);
+@@ -634,6 +636,7 @@ void __init uv_system_init(void)
+ 		uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask;
+ 		uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
+ 		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
++		uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
+ 		uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
+ 		uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
+ 		uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index 7e4a459..d869b3b 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -6,6 +6,7 @@
+ #include <asm/processor.h>
+ #include <asm/apic.h>
+ #include <asm/cpu.h>
++#include <asm/pci-direct.h>
+ 
+ #ifdef CONFIG_X86_64
+ # include <asm/numa_64.h>
+@@ -257,13 +258,15 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
+ {
+ #ifdef CONFIG_X86_HT
+ 	unsigned bits;
++	int cpu = smp_processor_id();
+ 
+ 	bits = c->x86_coreid_bits;
+-
+ 	/* Low order bits define the core id (index of core in socket) */
+ 	c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
+ 	/* Convert the initial APIC ID into the socket ID */
+ 	c->phys_proc_id = c->initial_apicid >> bits;
++	/* use socket ID also for last level cache */
++	per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+ #endif
+ }
+ 
+@@ -351,6 +354,15 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
+ 		    (c->x86_model == 8 && c->x86_mask >= 8))
+ 			set_cpu_cap(c, X86_FEATURE_K6_MTRR);
+ #endif
++#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
++	/* check CPU config space for extended APIC ID */
++	if (c->x86 >= 0xf) {
++		unsigned int val;
++		val = read_pci_config(0, 24, 0, 0x68);
++		if ((val & ((1 << 17) | (1 << 18))) == ((1 << 17) | (1 << 18)))
++			set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
++	}
++#endif
+ }
+ 
+ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
+diff --git a/arch/x86/kernel/cpu/mcheck/mce_32.c b/arch/x86/kernel/cpu/mcheck/mce_32.c
+index 3552119..07b523c 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce_32.c
++++ b/arch/x86/kernel/cpu/mcheck/mce_32.c
+@@ -29,6 +29,7 @@ static void unexpected_machine_check(struct pt_regs *regs, long error_code)
+ 
+ /* Call the installed machine check handler for this CPU setup. */
+ void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
++EXPORT_SYMBOL_GPL(machine_check_vector);
+ 
+ /* This has to be run for each processor */
+ void mcheck_init(struct cpuinfo_x86 *c)
+diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
+index 09dd1d4..289cc48 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
++++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
+@@ -420,6 +420,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
+  out2:
+ 	atomic_dec(&mce_entry);
+ }
++EXPORT_SYMBOL_GPL(do_machine_check);
+ 
+ #ifdef CONFIG_X86_MCE_INTEL
+ /***
+diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
+index 81408b9..dedc2bd 100644
+--- a/arch/x86/kernel/hpet.c
++++ b/arch/x86/kernel/hpet.c
+@@ -510,7 +510,8 @@ static int hpet_setup_irq(struct hpet_dev *dev)
+ {
+ 
+ 	if (request_irq(dev->irq, hpet_interrupt_handler,
+-			IRQF_DISABLED|IRQF_NOBALANCING, dev->name, dev))
++			IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
++			dev->name, dev))
+ 		return -1;
+ 
+ 	disable_irq(dev->irq);
+diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
+index b284b58..3065b40 100644
+--- a/arch/x86/kernel/pci-gart_64.c
++++ b/arch/x86/kernel/pci-gart_64.c
+@@ -688,8 +688,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
+ 
+ 	agp_gatt_table = gatt;
+ 
+-	enable_gart_translations();
+-
+ 	error = sysdev_class_register(&gart_sysdev_class);
+ 	if (!error)
+ 		error = sysdev_register(&device_gart);
+@@ -847,6 +845,14 @@ void __init gart_iommu_init(void)
+ 	wbinvd();
+ 
+ 	/*
++	 * Now all caches are flushed and we can safely enable
++	 * GART hardware.  Doing it early leaves the possibility
++	 * of stale cache entries that can lead to GART PTE
++	 * errors.
++	 */
++	enable_gart_translations();
++
++	/*
+ 	 * Try to workaround a bug (thanks to BenH):
+ 	 * Set unmapped entries to a scratch page instead of 0.
+ 	 * Any prefetches that hit unmapped entries won't get an bus abort
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
+index 667188e..d2d1ce8 100644
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -192,6 +192,15 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
+ 			DMI_MATCH(DMI_BOARD_NAME, "0KP561"),
+ 		},
+ 	},
++	{   /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
++		.callback = set_bios_reboot,
++		.ident = "Dell OptiPlex 360",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 360"),
++			DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
++		},
++	},
+ 	{	/* Handle problems with rebooting on Dell 2400's */
+ 		.callback = set_bios_reboot,
+ 		.ident = "Dell PowerEdge 2400",
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index b415843..0acc6a7 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -293,15 +293,13 @@ static void __init reserve_brk(void)
+ 
+ #ifdef CONFIG_BLK_DEV_INITRD
+ 
+-#ifdef CONFIG_X86_32
+-
+ #define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
+ static void __init relocate_initrd(void)
+ {
+ 
+ 	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
+ 	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+-	u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
++	u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
+ 	u64 ramdisk_here;
+ 	unsigned long slop, clen, mapaddr;
+ 	char *p, *q;
+@@ -357,14 +355,13 @@ static void __init relocate_initrd(void)
+ 		ramdisk_image, ramdisk_image + ramdisk_size - 1,
+ 		ramdisk_here, ramdisk_here + ramdisk_size - 1);
+ }
+-#endif
+ 
+ static void __init reserve_initrd(void)
+ {
+ 	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
+ 	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+ 	u64 ramdisk_end   = ramdisk_image + ramdisk_size;
+-	u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
++	u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
+ 
+ 	if (!boot_params.hdr.type_of_loader ||
+ 	    !ramdisk_image || !ramdisk_size)
+@@ -394,14 +391,8 @@ static void __init reserve_initrd(void)
+ 		return;
+ 	}
+ 
+-#ifdef CONFIG_X86_32
+ 	relocate_initrd();
+-#else
+-	printk(KERN_ERR "initrd extends beyond end of memory "
+-	       "(0x%08llx > 0x%08llx)\ndisabling initrd\n",
+-	       ramdisk_end, end_of_lowmem);
+-	initrd_start = 0;
+-#endif
++
+ 	free_early(ramdisk_image, ramdisk_end);
+ }
+ #else
+diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
+index 8c7b03b..8ccabb8 100644
+--- a/arch/x86/kernel/tlb_uv.c
++++ b/arch/x86/kernel/tlb_uv.c
+@@ -711,25 +711,31 @@ uv_activation_descriptor_init(int node, int pnode)
+ 	unsigned long pa;
+ 	unsigned long m;
+ 	unsigned long n;
+-	unsigned long mmr_image;
+ 	struct bau_desc *adp;
+ 	struct bau_desc *ad2;
+ 
+-	adp = (struct bau_desc *)kmalloc_node(16384, GFP_KERNEL, node);
++	/*
++	 * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
++	 * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per blade
++	 */
++	adp = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
++		UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
+ 	BUG_ON(!adp);
+ 
+ 	pa = uv_gpa(adp); /* need the real nasid*/
+ 	n = pa >> uv_nshift;
+ 	m = pa & uv_mmask;
+ 
+-	mmr_image = uv_read_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE);
+-	if (mmr_image) {
+-		uv_write_global_mmr64(pnode, (unsigned long)
+-				      UVH_LB_BAU_SB_DESCRIPTOR_BASE,
+-				      (n << UV_DESC_BASE_PNODE_SHIFT | m));
+-	}
++	uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE,
++			      (n << UV_DESC_BASE_PNODE_SHIFT | m));
+ 
+-	for (i = 0, ad2 = adp; i < UV_ACTIVATION_DESCRIPTOR_SIZE; i++, ad2++) {
++	/*
++	 * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each
++	 * cpu even though we only use the first one; one descriptor can
++	 * describe a broadcast to 256 nodes.
++	 */
++	for (i = 0, ad2 = adp; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR);
++		i++, ad2++) {
+ 		memset(ad2, 0, sizeof(struct bau_desc));
+ 		ad2->header.sw_ack_flag = 1;
+ 		/*
+diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
+index d57de05..cf8611d 100644
+--- a/arch/x86/kernel/tsc.c
++++ b/arch/x86/kernel/tsc.c
+@@ -710,7 +710,16 @@ static cycle_t read_tsc(struct clocksource *cs)
+ #ifdef CONFIG_X86_64
+ static cycle_t __vsyscall_fn vread_tsc(void)
+ {
+-	cycle_t ret = (cycle_t)vget_cycles();
++	cycle_t ret;
++
++	/*
++	 * Surround the RDTSC by barriers, to make sure it's not
++	 * speculated to outside the seqlock critical section and
++	 * does not cause time warps:
++	 */
++	rdtsc_barrier();
++	ret = (cycle_t)vget_cycles();
++	rdtsc_barrier();
+ 
+ 	return ret >= __vsyscall_gtod_data.clock.cycle_last ?
+ 		ret : __vsyscall_gtod_data.clock.cycle_last;
+diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
+index d7ac84e..6a17769 100644
+--- a/arch/x86/kernel/vm86_32.c
++++ b/arch/x86/kernel/vm86_32.c
+@@ -287,10 +287,9 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
+ 	info->regs.pt.ds = 0;
+ 	info->regs.pt.es = 0;
+ 	info->regs.pt.fs = 0;
+-
+-/* we are clearing gs later just before "jmp resume_userspace",
+- * because it is not saved/restored.
+- */
++#ifndef CONFIG_X86_32_LAZY_GS
++	info->regs.pt.gs = 0;
++#endif
+ 
+ /*
+  * The flags register is also special: we cannot trust that the user
+@@ -343,7 +342,9 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
+ 	__asm__ __volatile__(
+ 		"movl %0,%%esp\n\t"
+ 		"movl %1,%%ebp\n\t"
++#ifdef CONFIG_X86_32_LAZY_GS
+ 		"mov  %2, %%gs\n\t"
++#endif
+ 		"jmp resume_userspace"
+ 		: /* no outputs */
+ 		:"r" (&info->regs), "r" (task_thread_info(tsk)), "r" (0));
+diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
+index 44153af..25ee06a 100644
+--- a/arch/x86/kernel/vsyscall_64.c
++++ b/arch/x86/kernel/vsyscall_64.c
+@@ -132,15 +132,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv)
+ 			return;
+ 		}
+ 
+-		/*
+-		 * Surround the RDTSC by barriers, to make sure it's not
+-		 * speculated to outside the seqlock critical section and
+-		 * does not cause time warps:
+-		 */
+-		rdtsc_barrier();
+ 		now = vread();
+-		rdtsc_barrier();
+-
+ 		base = __vsyscall_gtod_data.clock.cycle_last;
+ 		mask = __vsyscall_gtod_data.clock.mask;
+ 		mult = __vsyscall_gtod_data.clock.mult;
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index bb48133..fa0adcd 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -32,6 +32,7 @@
+ #include <asm/desc.h>
+ #include <asm/vmx.h>
+ #include <asm/virtext.h>
++#include <asm/mce.h>
+ 
+ #define __ex(x) __kvm_handle_fault_on_reboot(x)
+ 
+@@ -97,6 +98,8 @@ struct vcpu_vmx {
+ 	int soft_vnmi_blocked;
+ 	ktime_t entry_time;
+ 	s64 vnmi_blocked_time;
++
++	u32 exit_reason;
+ };
+ 
+ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
+@@ -478,7 +481,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
+ {
+ 	u32 eb;
+ 
+-	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR);
++	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR);
+ 	if (!vcpu->fpu_active)
+ 		eb |= 1u << NM_VECTOR;
+ 	if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
+@@ -2585,6 +2588,35 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
+ 	return 0;
+ }
+ 
++/*
++ * Trigger machine check on the host. We assume all the MSRs are already set up
++ * by the CPU and that we still run on the same CPU as the MCE occurred on.
++ * We pass a fake environment to the machine check handler because we want
++ * the guest to be always treated like user space, no matter what context
++ * it used internally.
++ */
++static void kvm_machine_check(void)
++{
++#ifdef CONFIG_X86_MCE
++	struct pt_regs regs = {
++		.cs = 3, /* Fake ring 3 no matter what the guest ran on */
++		.flags = X86_EFLAGS_IF,
++	};
++
++#ifdef CONFIG_X86_64
++	do_machine_check(&regs, 0);
++#else
++	machine_check_vector(&regs, 0);
++#endif
++#endif
++}
++
++static int handle_machine_check(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
++{
++	/* already handled by vcpu_run */
++	return 1;
++}
++
+ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+ {
+ 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+@@ -2596,6 +2628,10 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+ 	vect_info = vmx->idt_vectoring_info;
+ 	intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+ 
++	ex_no = intr_info & INTR_INFO_VECTOR_MASK;
++	if (ex_no == MC_VECTOR)
++		return handle_machine_check(vcpu, kvm_run);
++
+ 	if ((vect_info & VECTORING_INFO_VALID_MASK) &&
+ 						!is_page_fault(intr_info))
+ 		printk(KERN_ERR "%s: unexpected, vectoring info 0x%x "
+@@ -2648,7 +2684,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+ 		return 1;
+ 	}
+ 
+-	ex_no = intr_info & INTR_INFO_VECTOR_MASK;
+ 	switch (ex_no) {
+ 	case DB_VECTOR:
+ 		dr6 = vmcs_readl(EXIT_QUALIFICATION);
+@@ -2978,6 +3013,12 @@ static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+ 	return 1;
+ }
+ 
++static int handle_vmx_insn(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
++{
++	kvm_queue_exception(vcpu, UD_VECTOR);
++	return 1;
++}
++
+ static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+ {
+ 	u64 exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+@@ -3145,11 +3186,21 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
+ 	[EXIT_REASON_HLT]                     = handle_halt,
+ 	[EXIT_REASON_INVLPG]		      = handle_invlpg,
+ 	[EXIT_REASON_VMCALL]                  = handle_vmcall,
++	[EXIT_REASON_VMCLEAR]	              = handle_vmx_insn,
++	[EXIT_REASON_VMLAUNCH]                = handle_vmx_insn,
++	[EXIT_REASON_VMPTRLD]                 = handle_vmx_insn,
++	[EXIT_REASON_VMPTRST]                 = handle_vmx_insn,
++	[EXIT_REASON_VMREAD]                  = handle_vmx_insn,
++	[EXIT_REASON_VMRESUME]                = handle_vmx_insn,
++	[EXIT_REASON_VMWRITE]                 = handle_vmx_insn,
++	[EXIT_REASON_VMOFF]                   = handle_vmx_insn,
++	[EXIT_REASON_VMON]                    = handle_vmx_insn,
+ 	[EXIT_REASON_TPR_BELOW_THRESHOLD]     = handle_tpr_below_threshold,
+ 	[EXIT_REASON_APIC_ACCESS]             = handle_apic_access,
+ 	[EXIT_REASON_WBINVD]                  = handle_wbinvd,
+ 	[EXIT_REASON_TASK_SWITCH]             = handle_task_switch,
+ 	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
++	[EXIT_REASON_MCE_DURING_VMENTRY]      = handle_machine_check,
+ };
+ 
+ static const int kvm_vmx_max_exit_handlers =
+@@ -3161,8 +3212,8 @@ static const int kvm_vmx_max_exit_handlers =
+  */
+ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
+ {
+-	u32 exit_reason = vmcs_read32(VM_EXIT_REASON);
+ 	struct vcpu_vmx *vmx = to_vmx(vcpu);
++	u32 exit_reason = vmx->exit_reason;
+ 	u32 vectoring_info = vmx->idt_vectoring_info;
+ 
+ 	KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu),
+@@ -3512,6 +3563,13 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+ 
+ 	intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+ 
++	vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
++
++	/* Handle machine checks before interrupts are enabled */
++	if ((vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY) ||
++		(intr_info & INTR_INFO_VECTOR_MASK) == MC_VECTOR)
++		kvm_machine_check();
++
+ 	/* We need to handle NMIs before interrupts are enabled */
+ 	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
+ 	    (intr_info & INTR_INFO_VALID_MASK)) {
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 3944e91..ee4714b 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -634,10 +634,12 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
+ 	if ((!vcpu->time_page))
+ 		return;
+ 
++	preempt_disable();
+ 	if (unlikely(vcpu->hv_clock_tsc_khz != __get_cpu_var(cpu_tsc_khz))) {
+ 		kvm_set_time_scale(__get_cpu_var(cpu_tsc_khz), &vcpu->hv_clock);
+ 		vcpu->hv_clock_tsc_khz = __get_cpu_var(cpu_tsc_khz);
+ 	}
++	preempt_enable();
+ 
+ 	/* Keep irq disabled to prevent changes to the clock */
+ 	local_irq_save(flags);
+@@ -3934,7 +3936,13 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+ 
+ 	vcpu->arch.cr2 = sregs->cr2;
+ 	mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3;
+-	vcpu->arch.cr3 = sregs->cr3;
++
++	down_read(&vcpu->kvm->slots_lock);
++	if (gfn_to_memslot(vcpu->kvm, sregs->cr3 >> PAGE_SHIFT))
++		vcpu->arch.cr3 = sregs->cr3;
++	else
++		set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
++	up_read(&vcpu->kvm->slots_lock);
+ 
+ 	kvm_set_cr8(vcpu, sregs->cr8);
+ 
+diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c
+index 605c8be..c0bedcd 100644
+--- a/arch/x86/mm/memtest.c
++++ b/arch/x86/mm/memtest.c
+@@ -40,23 +40,23 @@ static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad)
+ 
+ static void __init memtest(u64 pattern, u64 start_phys, u64 size)
+ {
+-	u64 i, count;
+-	u64 *start;
++	u64 *p;
++	void *start, *end;
+ 	u64 start_bad, last_bad;
+ 	u64 start_phys_aligned;
+ 	size_t incr;
+ 
+ 	incr = sizeof(pattern);
+ 	start_phys_aligned = ALIGN(start_phys, incr);
+-	count = (size - (start_phys_aligned - start_phys))/incr;
+ 	start = __va(start_phys_aligned);
++	end = start + size - (start_phys_aligned - start_phys);
+ 	start_bad = 0;
+ 	last_bad = 0;
+ 
+-	for (i = 0; i < count; i++)
+-		start[i] = pattern;
+-	for (i = 0; i < count; i++, start++, start_phys_aligned += incr) {
+-		if (*start == pattern)
++	for (p = start; p < end; p++)
++		*p = pattern;
++	for (p = start; p < end; p++, start_phys_aligned += incr) {
++		if (*p == pattern)
+ 			continue;
+ 		if (start_phys_aligned == last_bad + incr) {
+ 			last_bad += incr;
+diff --git a/drivers/char/epca.c b/drivers/char/epca.c
+index af7c13c..bcd07cb 100644
+--- a/drivers/char/epca.c
++++ b/drivers/char/epca.c
+@@ -1518,7 +1518,7 @@ static void doevent(int crd)
+ 		if (event & MODEMCHG_IND) {
+ 			/* A modem signal change has been indicated */
+ 			ch->imodem = mstat;
+-			if (test_bit(ASYNC_CHECK_CD, &ch->port.flags)) {
++			if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) {
+ 				/* We are now receiving dcd */
+ 				if (mstat & ch->dcd)
+ 					wake_up_interruptible(&ch->port.open_wait);
+@@ -1765,9 +1765,9 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
+ 		 * that the driver will wait on carrier detect.
+ 		 */
+ 		if (ts->c_cflag & CLOCAL)
+-			clear_bit(ASYNC_CHECK_CD, &ch->port.flags);
++			clear_bit(ASYNCB_CHECK_CD, &ch->port.flags);
+ 		else
+-			set_bit(ASYNC_CHECK_CD, &ch->port.flags);
++			set_bit(ASYNCB_CHECK_CD, &ch->port.flags);
+ 		mval = ch->m_dtr | ch->m_rts;
+ 	} /* End CBAUD not detected */
+ 	iflag = termios2digi_i(ch, ts->c_iflag);
+@@ -2244,7 +2244,8 @@ static void do_softint(struct work_struct *work)
+ 			if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
+ 				tty_hangup(tty);
+ 				wake_up_interruptible(&ch->port.open_wait);
+-				clear_bit(ASYNC_NORMAL_ACTIVE, &ch->port.flags);
++				clear_bit(ASYNCB_NORMAL_ACTIVE,
++						&ch->port.flags);
+ 			}
+ 		}
+ 		tty_kref_put(tty);
+diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
+index 4a4cab7..a57ab11 100644
+--- a/drivers/char/moxa.c
++++ b/drivers/char/moxa.c
+@@ -1184,6 +1184,11 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
+ 		return -ENODEV;
+ 	}
+ 
++	if (port % MAX_PORTS_PER_BOARD >= brd->numPorts) {
++		retval = -ENODEV;
++		goto out_unlock;
++	}
++
+ 	ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
+ 	ch->port.count++;
+ 	tty->driver_data = ch;
+@@ -1208,8 +1213,8 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
+ 				moxa_close_port(tty);
+ 	} else
+ 		ch->port.flags |= ASYNC_NORMAL_ACTIVE;
++out_unlock:
+ 	mutex_unlock(&moxa_openlock);
+-
+ 	return retval;
+ }
+ 
+diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
+index d2e93e3..2e99158 100644
+--- a/drivers/char/n_r3964.c
++++ b/drivers/char/n_r3964.c
+@@ -1062,7 +1062,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+ 	struct r3964_client_info *pClient;
+ 	struct r3964_message *pMsg;
+ 	struct r3964_client_message theMsg;
+-	int count;
++	int ret;
+ 
+ 	TRACE_L("read()");
+ 
+@@ -1074,8 +1074,8 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+ 		if (pMsg == NULL) {
+ 			/* no messages available. */
+ 			if (file->f_flags & O_NONBLOCK) {
+-				unlock_kernel();
+-				return -EAGAIN;
++				ret = -EAGAIN;
++				goto unlock;
+ 			}
+ 			/* block until there is a message: */
+ 			wait_event_interruptible(pInfo->read_wait,
+@@ -1085,29 +1085,31 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+ 		/* If we still haven't got a message, we must have been signalled */
+ 
+ 		if (!pMsg) {
+-			unlock_kernel();
+-			return -EINTR;
++			ret = -EINTR;
++			goto unlock;
+ 		}
+ 
+ 		/* deliver msg to client process: */
+ 		theMsg.msg_id = pMsg->msg_id;
+ 		theMsg.arg = pMsg->arg;
+ 		theMsg.error_code = pMsg->error_code;
+-		count = sizeof(struct r3964_client_message);
++		ret = sizeof(struct r3964_client_message);
+ 
+ 		kfree(pMsg);
+ 		TRACE_M("r3964_read - msg kfree %p", pMsg);
+ 
+-		if (copy_to_user(buf, &theMsg, count)) {
+-			unlock_kernel();
+-			return -EFAULT;
++		if (copy_to_user(buf, &theMsg, ret)) {
++			ret = -EFAULT;
++			goto unlock;
+ 		}
+ 
+-		TRACE_PS("read - return %d", count);
+-		return count;
++		TRACE_PS("read - return %d", ret);
++		goto unlock;
+ 	}
++	ret = -EPERM;
++unlock:
+ 	unlock_kernel();
+-	return -EPERM;
++	return ret;
+ }
+ 
+ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
+diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
+index dbb9125..881934c 100644
+--- a/drivers/char/pcmcia/cm4000_cs.c
++++ b/drivers/char/pcmcia/cm4000_cs.c
+@@ -1575,7 +1575,8 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ 		clear_bit(LOCK_IO, &dev->flags);
+ 		wake_up_interruptible(&dev->ioq);
+ 
+-		return 0;
++		rc = 0;
++		break;
+ 	case CM_IOCSPTS:
+ 		{
+ 			struct ptsreq krnptsreq;
+diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
+index f59fc5c..3fa7234 100644
+--- a/drivers/char/rocket.c
++++ b/drivers/char/rocket.c
+@@ -934,7 +934,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
+ 	/*
+ 	 * Info->count is now 1; so it's safe to sleep now.
+ 	 */
+-	if (!test_bit(ASYNC_INITIALIZED, &port->flags)) {
++	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+ 		cp = &info->channel;
+ 		sSetRxTrigger(cp, TRIG_1);
+ 		if (sGetChanStatus(cp) & CD_ACT)
+@@ -958,7 +958,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
+ 		sEnRxFIFO(cp);
+ 		sEnTransmit(cp);
+ 
+-		set_bit(ASYNC_INITIALIZED, &info->port.flags);
++		set_bit(ASYNCB_INITIALIZED, &info->port.flags);
+ 
+ 		/*
+ 		 * Set up the tty->alt_speed kludge
+@@ -1641,7 +1641,7 @@ static int rp_write(struct tty_struct *tty,
+ 	/*  Write remaining data into the port's xmit_buf */
+ 	while (1) {
+ 		/* Hung up ? */
+-		if (!test_bit(ASYNC_NORMAL_ACTIVE, &info->port.flags))
++		if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
+ 			goto end;
+ 		c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
+ 		c = min(c, XMIT_BUF_SIZE - info->xmit_head);
+diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
+index e6ce632..7539bed 100644
+--- a/drivers/char/vt_ioctl.c
++++ b/drivers/char/vt_ioctl.c
+@@ -396,7 +396,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
+ 	kbd = kbd_table + console;
+ 	switch (cmd) {
+ 	case TIOCLINUX:
+-		return tioclinux(tty, arg);
++		ret = tioclinux(tty, arg);
++		break;
+ 	case KIOCSOUND:
+ 		if (!perm)
+ 			goto eperm;
+diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
+index 05aa2d4..d5ea8a6 100644
+--- a/drivers/firmware/memmap.c
++++ b/drivers/firmware/memmap.c
+@@ -31,8 +31,12 @@
+  * information is necessary as for the resource tree.
+  */
+ struct firmware_map_entry {
+-	resource_size_t		start;	/* start of the memory range */
+-	resource_size_t		end;	/* end of the memory range (incl.) */
++	/*
++	 * start and end must be u64 rather than resource_size_t, because e820
++	 * resources can lie at addresses above 4G.
++	 */
++	u64			start;	/* start of the memory range */
++	u64			end;	/* end of the memory range (incl.) */
+ 	const char		*type;	/* type of the memory range */
+ 	struct list_head	list;	/* entry for the linked list */
+ 	struct kobject		kobj;   /* kobject for each entry */
+@@ -101,7 +105,7 @@ static LIST_HEAD(map_entries);
+  * Common implementation of firmware_map_add() and firmware_map_add_early()
+  * which expects a pre-allocated struct firmware_map_entry.
+  **/
+-static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
++static int firmware_map_add_entry(u64 start, u64 end,
+ 				  const char *type,
+ 				  struct firmware_map_entry *entry)
+ {
+@@ -132,8 +136,7 @@ static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
+  *
+  * Returns 0 on success, or -ENOMEM if no memory could be allocated.
+  **/
+-int firmware_map_add(resource_size_t start, resource_size_t end,
+-		     const char *type)
++int firmware_map_add(u64 start, u64 end, const char *type)
+ {
+ 	struct firmware_map_entry *entry;
+ 
+@@ -157,8 +160,7 @@ int firmware_map_add(resource_size_t start, resource_size_t end,
+  *
+  * Returns 0 on success, or -ENOMEM if no memory could be allocated.
+  **/
+-int __init firmware_map_add_early(resource_size_t start, resource_size_t end,
+-				  const char *type)
++int __init firmware_map_add_early(u64 start, u64 end, const char *type)
+ {
+ 	struct firmware_map_entry *entry;
+ 
+diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
+index 98560e1..e3cb402 100644
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -67,8 +67,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
+ 
+ 	pci_save_state(dev->pdev);
+ 
+-	i915_save_state(dev);
+-
+ 	/* If KMS is active, we do the leavevt stuff here */
+ 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ 		if (i915_gem_idle(dev))
+@@ -77,6 +75,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
+ 		drm_irq_uninstall(dev);
+ 	}
+ 
++	i915_save_state(dev);
++
+ 	intel_opregion_free(dev, 1);
+ 
+ 	if (state.event == PM_EVENT_SUSPEND) {
+diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
+index 925eb9e..6368f57 100644
+--- a/drivers/ide/ide-cd.c
++++ b/drivers/ide/ide-cd.c
+@@ -758,7 +758,7 @@ out_end:
+ 				rq->errors = -EIO;
+ 		}
+ 
+-		if (uptodate == 0)
++		if (uptodate == 0 && rq->bio)
+ 			ide_cd_error_cmd(drive, cmd);
+ 
+ 		/* make sure it's fully ended */
+diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
+index 20724ae..c4a0264 100644
+--- a/drivers/infiniband/hw/mlx4/qp.c
++++ b/drivers/infiniband/hw/mlx4/qp.c
+@@ -1585,12 +1585,16 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ 				break;
+ 
+ 			case IB_WR_LOCAL_INV:
++				ctrl->srcrb_flags |=
++					cpu_to_be32(MLX4_WQE_CTRL_STRONG_ORDER);
+ 				set_local_inv_seg(wqe, wr->ex.invalidate_rkey);
+ 				wqe  += sizeof (struct mlx4_wqe_local_inval_seg);
+ 				size += sizeof (struct mlx4_wqe_local_inval_seg) / 16;
+ 				break;
+ 
+ 			case IB_WR_FAST_REG_MR:
++				ctrl->srcrb_flags |=
++					cpu_to_be32(MLX4_WQE_CTRL_STRONG_ORDER);
+ 				set_fmr_seg(wqe, wr);
+ 				wqe  += sizeof (struct mlx4_wqe_fmr_seg);
+ 				size += sizeof (struct mlx4_wqe_fmr_seg) / 16;
+diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
+index f126566..3d337d9 100644
+--- a/drivers/isdn/hisax/hfc_pci.c
++++ b/drivers/isdn/hisax/hfc_pci.c
+@@ -82,8 +82,9 @@ release_io_hfcpci(struct IsdnCardState *cs)
+ 	Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
+ 	pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0);	/* disable memory mapped ports + busmaster */
+ 	del_timer(&cs->hw.hfcpci.timer);
+-	kfree(cs->hw.hfcpci.share_start);
+-	cs->hw.hfcpci.share_start = NULL;
++	pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
++		cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
++	cs->hw.hfcpci.fifos = NULL;
+ 	iounmap((void *)cs->hw.hfcpci.pci_io);
+ }
+ 
+@@ -1663,8 +1664,19 @@ setup_hfcpci(struct IsdnCard *card)
+ 					     dev_hfcpci);
+ 		i++;
+ 		if (tmp_hfcpci) {
++			dma_addr_t	dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL;
+ 			if (pci_enable_device(tmp_hfcpci))
+ 				continue;
++			if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) {
++				printk(KERN_WARNING
++					"HiSax hfc_pci: No suitable DMA available.\n");
++				continue;
++			}
++			if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) {
++				printk(KERN_WARNING
++					"HiSax hfc_pci: No suitable consistent DMA available.\n");
++				continue;
++			}
+ 			pci_set_master(tmp_hfcpci);
+ 			if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
+ 				continue;
+@@ -1693,22 +1705,29 @@ setup_hfcpci(struct IsdnCard *card)
+ 		printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
+ 		return (0);
+ 	}
++
+ 	/* Allocate memory for FIFOS */
+-	/* Because the HFC-PCI needs a 32K physical alignment, we */
+-	/* need to allocate the double mem and align the address */
+-	if (!(cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) {
+-		printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n");
++	cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev,
++					0x8000, &cs->hw.hfcpci.dma);
++	if (!cs->hw.hfcpci.fifos) {
++		printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n");
++		return 0;
++	}
++	if (cs->hw.hfcpci.dma & 0x7fff) {
++		printk(KERN_WARNING
++		    "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n",
++		    (u_long)cs->hw.hfcpci.dma);
++		pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
++			cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
+ 		return 0;
+ 	}
+-	cs->hw.hfcpci.fifos = (void *)
+-	    (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000;
+-	pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos));
++	pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma);
+ 	cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256);
+ 	printk(KERN_INFO
+-	       "HFC-PCI: defined at mem %p fifo %p(%#x) IRQ %d HZ %d\n",
++	       "HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n",
+ 	       cs->hw.hfcpci.pci_io,
+ 	       cs->hw.hfcpci.fifos,
+-	       (u_int) virt_to_bus(cs->hw.hfcpci.fifos),
++	       (u_long)cs->hw.hfcpci.dma,
+ 	       cs->irq, HZ);
+ 
+ 	spin_lock_irqsave(&cs->lock, flags);
+diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
+index f852704..0685c19 100644
+--- a/drivers/isdn/hisax/hisax.h
++++ b/drivers/isdn/hisax/hisax.h
+@@ -703,7 +703,7 @@ struct hfcPCI_hw {
+         int nt_timer;
+         struct pci_dev *dev;
+         unsigned char *pci_io; /* start of PCI IO memory */
+-        void *share_start; /* shared memory for Fifos start */
++	dma_addr_t dma; /* dma handle for Fifos */
+         void *fifos; /* FIFO memory */ 
+         int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
+ 	struct timer_list timer;
+diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
+index a2e26c2..14ce11e 100644
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -195,7 +195,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ 			      struct dm_exception_store **store)
+ {
+ 	int r = 0;
+-	struct dm_exception_store_type *type;
++	struct dm_exception_store_type *type = NULL;
+ 	struct dm_exception_store *tmp_store;
+ 	char persistent;
+ 
+@@ -211,12 +211,15 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ 	}
+ 
+ 	persistent = toupper(*argv[1]);
+-	if (persistent != 'P' && persistent != 'N') {
++	if (persistent == 'P')
++		type = get_type("P");
++	else if (persistent == 'N')
++		type = get_type("N");
++	else {
+ 		ti->error = "Persistent flag is not P or N";
+ 		return -EINVAL;
+ 	}
+ 
+-	type = get_type(argv[1]);
+ 	if (!type) {
+ 		ti->error = "Exception store type not recognised";
+ 		r = -EINVAL;
+diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
+index 0a2e6e7..96a796b 100644
+--- a/drivers/md/dm-exception-store.h
++++ b/drivers/md/dm-exception-store.h
+@@ -156,7 +156,7 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e)
+  */
+ static inline sector_t get_dev_size(struct block_device *bdev)
+ {
+-	return bdev->bd_inode->i_size >> SECTOR_SHIFT;
++	return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
+ }
+ 
+ static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
+diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
+index be233bc..5eaa954 100644
+--- a/drivers/md/dm-log.c
++++ b/drivers/md/dm-log.c
+@@ -415,7 +415,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
+ 		buf_size = dm_round_up((LOG_OFFSET << SECTOR_SHIFT) +
+ 				       bitset_size, ti->limits.hardsect_size);
+ 
+-		if (buf_size > dev->bdev->bd_inode->i_size) {
++		if (buf_size > i_size_read(dev->bdev->bd_inode)) {
+ 			DMWARN("log device %s too small: need %llu bytes",
+ 				dev->name, (unsigned long long)buf_size);
+ 			kfree(lc);
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index 6a386ab..3a8f827 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -553,6 +553,12 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg,
+ 		return -EINVAL;
+ 	}
+ 
++	if (ps_argc > as->argc) {
++		dm_put_path_selector(pst);
++		ti->error = "not enough arguments for path selector";
++		return -EINVAL;
++	}
++
+ 	r = pst->create(&pg->ps, ps_argc, as->argv);
+ 	if (r) {
+ 		dm_put_path_selector(pst);
+@@ -699,6 +705,11 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m)
+ 	if (!hw_argc)
+ 		return 0;
+ 
++	if (hw_argc > as->argc) {
++		ti->error = "not enough arguments for hardware handler";
++		return -EINVAL;
++	}
++
+ 	m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL);
+ 	request_module("scsi_dh_%s", m->hw_handler_name);
+ 	if (scsi_dh_handler_exist(m->hw_handler_name) == 0) {
+@@ -836,6 +847,7 @@ static void multipath_dtr(struct dm_target *ti)
+ 
+ 	flush_workqueue(kmpath_handlerd);
+ 	flush_workqueue(kmultipathd);
++	flush_scheduled_work();
+ 	free_multipath(m);
+ }
+ 
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 429b50b..c5c4a0d 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -387,7 +387,8 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
+ static int check_device_area(struct dm_dev_internal *dd, sector_t start,
+ 			     sector_t len)
+ {
+-	sector_t dev_size = dd->dm_dev.bdev->bd_inode->i_size >> SECTOR_SHIFT;
++	sector_t dev_size = i_size_read(dd->dm_dev.bdev->bd_inode) >>
++			    SECTOR_SHIFT;
+ 
+ 	if (!dev_size)
+ 		return 1;
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 424f7b0..add49c1 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1780,6 +1780,10 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj)
+ 	if (&md->kobj != kobj)
+ 		return NULL;
+ 
++	if (test_bit(DMF_FREEING, &md->flags) ||
++	    test_bit(DMF_DELETING, &md->flags))
++		return NULL;
++
+ 	dm_get(md);
+ 	return md;
+ }
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index bb37fb1..c0434e0 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -3696,6 +3696,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
+ 				spin_unlock_irq(&conf->device_lock);
+ 				if (must_retry) {
+ 					release_stripe(sh);
++					schedule();
+ 					goto retry;
+ 				}
+ 			}
+diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
+index d92d055..fde8c59 100644
+--- a/drivers/media/dvb/frontends/lgdt3305.c
++++ b/drivers/media/dvb/frontends/lgdt3305.c
+@@ -19,6 +19,7 @@
+  *
+  */
+ 
++#include <asm/div64.h>
+ #include <linux/dvb/frontend.h>
+ #include "dvb_math.h"
+ #include "lgdt3305.h"
+@@ -496,27 +497,15 @@ static int lgdt3305_set_if(struct lgdt3305_state *state,
+ 
+ 	nco = if_freq_khz / 10;
+ 
+-#define LGDT3305_64BIT_DIVISION_ENABLED 0
+-	/* FIXME: 64bit division disabled to avoid linking error:
+-	 * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
+-	 */
+ 	switch (param->u.vsb.modulation) {
+ 	case VSB_8:
+-#if LGDT3305_64BIT_DIVISION_ENABLED
+ 		nco <<= 24;
+-		nco /= 625;
+-#else
+-		nco *= ((1 << 24) / 625);
+-#endif
++		do_div(nco, 625);
+ 		break;
+ 	case QAM_64:
+ 	case QAM_256:
+-#if LGDT3305_64BIT_DIVISION_ENABLED
+ 		nco <<= 28;
+-		nco /= 625;
+-#else
+-		nco *= ((1 << 28) / 625);
+-#endif
++		do_div(nco, 625);
+ 		break;
+ 	default:
+ 		return -EINVAL;
+diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
+index 3f1a035..448c306 100644
+--- a/drivers/media/video/Makefile
++++ b/drivers/media/video/Makefile
+@@ -12,6 +12,8 @@ omap2cam-objs	:=	omap24xxcam.o omap24xxcam-dma.o
+ 
+ videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o
+ 
++# V4L2 core modules
++
+ obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
+ ifeq ($(CONFIG_COMPAT),y)
+   obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o
+@@ -23,21 +25,15 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
+   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
+ endif
+ 
+-obj-$(CONFIG_VIDEO_TUNER) += tuner.o
++# All i2c modules must come first:
+ 
+-obj-$(CONFIG_VIDEO_BT848) += bt8xx/
+-obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
++obj-$(CONFIG_VIDEO_TUNER) += tuner.o
+ obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
+ obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
+ obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
+-
+ obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
+ obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
+ obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
+-obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
+-obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
+-obj-$(CONFIG_VIDEO_W9966) += w9966.o
+-
+ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
+ obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
+ obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
+@@ -54,11 +50,40 @@ obj-$(CONFIG_VIDEO_BT819) += bt819.o
+ obj-$(CONFIG_VIDEO_BT856) += bt856.o
+ obj-$(CONFIG_VIDEO_BT866) += bt866.o
+ obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
++obj-$(CONFIG_VIDEO_VINO) += indycam.o
++obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
++obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
++obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
++obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
++obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
++obj-$(CONFIG_VIDEO_M52790) += m52790.o
++obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
++obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
++obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
++obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
++obj-$(CONFIG_VIDEO_CX25840) += cx25840/
++obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
++obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
++obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
++obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
++obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
+ 
+-obj-$(CONFIG_VIDEO_ZORAN) += zoran/
++obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
++obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
++obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
++obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
++obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
++obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
+ 
++# And now the v4l2 drivers:
++
++obj-$(CONFIG_VIDEO_BT848) += bt8xx/
++obj-$(CONFIG_VIDEO_ZORAN) += zoran/
++obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
++obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
++obj-$(CONFIG_VIDEO_W9966) += w9966.o
+ obj-$(CONFIG_VIDEO_PMS) += pms.o
+-obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
++obj-$(CONFIG_VIDEO_VINO) += vino.o
+ obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
+ obj-$(CONFIG_VIDEO_CPIA) += cpia.o
+ obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
+@@ -69,17 +94,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
+ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+ obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
+ obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
+-obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
+-obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
+ obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
+-obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
+-obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
+-obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
+-obj-$(CONFIG_VIDEO_M52790) += m52790.o
+-obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
+-obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
+-obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+-obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
+ obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
+ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
+ obj-$(CONFIG_VIDEO_MXB) += mxb.o
+@@ -92,19 +107,12 @@ obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
+ obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
+ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
+ obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
+-obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
+ 
+ obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
+ 
+-obj-$(CONFIG_VIDEO_CX25840) += cx25840/
+-obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
+-obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
+ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
+ 
+ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
+-obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
+-
+-obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
+ 
+ obj-$(CONFIG_USB_DABUSB)        += dabusb.o
+ obj-$(CONFIG_USB_OV511)         += ov511.o
+@@ -134,24 +142,21 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
+ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+ obj-$(CONFIG_VIDEO_CX23885) += cx23885/
+ 
++obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
++obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
++obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
++# soc-camera host drivers have to be linked after camera drivers
+ obj-$(CONFIG_VIDEO_MX1)			+= mx1_camera.o
+ obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.o
+ obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
+ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
+-obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
+-obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
+-obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
+-obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
+-obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
+-obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
+-obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
+-obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
+-obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
+ 
+ obj-$(CONFIG_VIDEO_AU0828) += au0828/
+ 
+ obj-$(CONFIG_USB_VIDEO_CLASS)	+= uvc/
+ 
++obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
++
+ EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+ EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+ EXTRA_CFLAGS += -Idrivers/media/common/tuners
+diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
+index 82fc2f9..3783b49 100644
+--- a/drivers/media/video/cx18/cx18-controls.c
++++ b/drivers/media/video/cx18/cx18-controls.c
+@@ -61,6 +61,8 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
+ 
+ 	switch (qctrl->id) {
+ 	/* Standard V4L2 controls */
++	case V4L2_CID_USER_CLASS:
++		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
+ 	case V4L2_CID_BRIGHTNESS:
+ 	case V4L2_CID_HUE:
+ 	case V4L2_CID_SATURATION:
+diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
+index 8ded529..4c8e958 100644
+--- a/drivers/media/video/cx2341x.c
++++ b/drivers/media/video/cx2341x.c
+@@ -500,6 +500,8 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
+ 	int err;
+ 
+ 	switch (qctrl->id) {
++	case V4L2_CID_MPEG_CLASS:
++		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
+ 	case V4L2_CID_MPEG_STREAM_TYPE:
+ 		return v4l2_ctrl_query_fill(qctrl,
+ 				V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
+index 84995bc..a3b77ed 100644
+--- a/drivers/media/video/ivtv/ivtv-controls.c
++++ b/drivers/media/video/ivtv/ivtv-controls.c
+@@ -60,6 +60,8 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
+ 
+ 	switch (qctrl->id) {
+ 	/* Standard V4L2 controls */
++	case V4L2_CID_USER_CLASS:
++		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
+ 	case V4L2_CID_BRIGHTNESS:
+ 	case V4L2_CID_HUE:
+ 	case V4L2_CID_SATURATION:
+diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+index add3395..c5563cf 100644
+--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
++++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+@@ -1978,6 +1978,34 @@ static unsigned int pvr2_copy_i2c_addr_list(
+ }
+ 
+ 
++static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
++{
++	/*
++	  Mike Isely <isely at pobox.com> 19-Nov-2006 - This bit of nuttiness
++	  for cx25840 causes that module to correctly set up its video
++	  scaling.  This is really a problem in the cx25840 module itself,
++	  but we work around it here.  The problem has not been seen in
++	  ivtv because there VBI is supported and set up.  We don't do VBI
++	  here (at least not yet) and thus we never attempted to even set
++	  it up.
++	*/
++	struct v4l2_format fmt;
++	if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) {
++		/* We're not using a cx25840 so don't enable the hack */
++		return;
++	}
++
++	pvr2_trace(PVR2_TRACE_INIT,
++		   "Module ID %u:"
++		   " Executing cx25840 VBI hack",
++		   hdw->decoder_client_id);
++	memset(&fmt, 0, sizeof(fmt));
++	fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
++	v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
++			     video, s_fmt, &fmt);
++}
++
++
+ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
+ 				const struct pvr2_device_client_desc *cd)
+ {
+@@ -2069,30 +2097,6 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
+ 	/* client-specific setup... */
+ 	switch (mid) {
+ 	case PVR2_CLIENT_ID_CX25840:
+-		hdw->decoder_client_id = mid;
+-		{
+-			/*
+-			  Mike Isely <isely at pobox.com> 19-Nov-2006 - This
+-			  bit of nuttiness for cx25840 causes that module
+-			  to correctly set up its video scaling.  This is
+-			  really a problem in the cx25840 module itself,
+-			  but we work around it here.  The problem has not
+-			  been seen in ivtv because there VBI is supported
+-			  and set up.  We don't do VBI here (at least not
+-			  yet) and thus we never attempted to even set it
+-			  up.
+-			*/
+-			struct v4l2_format fmt;
+-			pvr2_trace(PVR2_TRACE_INIT,
+-				   "Module ID %u:"
+-				   " Executing cx25840 VBI hack",
+-				   mid);
+-			memset(&fmt, 0, sizeof(fmt));
+-			fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+-			v4l2_device_call_all(&hdw->v4l2_dev, mid,
+-					     video, s_fmt, &fmt);
+-		}
+-		break;
+ 	case PVR2_CLIENT_ID_SAA7115:
+ 		hdw->decoder_client_id = mid;
+ 		break;
+@@ -2193,6 +2197,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
+ 		cptr->info->set_value(cptr,~0,cptr->info->default_value);
+ 	}
+ 
++	pvr2_hdw_cx25840_vbi_hack(hdw);
++
+ 	/* Set up special default values for the television and radio
+ 	   frequencies here.  It's not really important what these defaults
+ 	   are, but I set them to something usable in the Chicago area just
+@@ -2944,6 +2950,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
+ 			vs = hdw->std_mask_cur;
+ 			v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ 					     core, s_std, vs);
++			pvr2_hdw_cx25840_vbi_hack(hdw);
+ 		}
+ 		hdw->tuner_signal_stale = !0;
+ 		hdw->cropcap_stale = !0;
+@@ -4066,6 +4073,7 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
+ 	if (hdw->decoder_client_id) {
+ 		v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
+ 				     core, reset, 0);
++		pvr2_hdw_cx25840_vbi_hack(hdw);
+ 		return 0;
+ 	}
+ 	pvr2_trace(PVR2_TRACE_INIT,
+diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
+index 3dbaa19..604158a 100644
+--- a/drivers/media/video/saa7134/Makefile
++++ b/drivers/media/video/saa7134/Makefile
+@@ -3,8 +3,7 @@ saa7134-objs :=	saa7134-cards.o saa7134-core.o saa7134-i2c.o	\
+ 		saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o    \
+ 		saa7134-video.o saa7134-input.o
+ 
+-obj-$(CONFIG_VIDEO_SAA7134) +=  saa7134.o saa7134-empress.o \
+-				saa6752hs.o
++obj-$(CONFIG_VIDEO_SAA7134) +=  saa6752hs.o saa7134.o saa7134-empress.o
+ 
+ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
+ 
+diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
+index d287315..cd95093 100644
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -1538,6 +1538,7 @@ int bond_create_sysfs(void)
+ 			printk(KERN_ERR
+ 			       "network device named %s already exists in sysfs",
+ 			       class_attr_bonding_masters.attr.name);
++		ret = 0;
+ 	}
+ 
+ 	return ret;
+diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
+index ca82f19..42055a5 100644
+--- a/drivers/net/e1000e/netdev.c
++++ b/drivers/net/e1000e/netdev.c
+@@ -1996,7 +1996,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
+ 	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
+ 	struct e1000_hw *hw = &adapter->hw;
+ 	struct net_device *poll_dev = adapter->netdev;
+-	int tx_cleaned = 0, work_done = 0;
++	int tx_cleaned = 1, work_done = 0;
+ 
+ 	adapter = netdev_priv(poll_dev);
+ 
+diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
+index 6bb5af3..305e0d1 100644
+--- a/drivers/net/mv643xx_eth.c
++++ b/drivers/net/mv643xx_eth.c
+@@ -1751,12 +1751,12 @@ static void mv643xx_eth_program_unicast_filter(struct net_device *dev)
+ 
+ 	uc_addr_set(mp, dev->dev_addr);
+ 
+-	port_config = rdlp(mp, PORT_CONFIG);
++	port_config = rdlp(mp, PORT_CONFIG) & ~UNICAST_PROMISCUOUS_MODE;
++
+ 	nibbles = uc_addr_filter_mask(dev);
+ 	if (!nibbles) {
+ 		port_config |= UNICAST_PROMISCUOUS_MODE;
+-		wrlp(mp, PORT_CONFIG, port_config);
+-		return;
++		nibbles = 0xffff;
+ 	}
+ 
+ 	for (i = 0; i < 16; i += 4) {
+@@ -1777,7 +1777,6 @@ static void mv643xx_eth_program_unicast_filter(struct net_device *dev)
+ 		wrl(mp, off, v);
+ 	}
+ 
+-	port_config &= ~UNICAST_PROMISCUOUS_MODE;
+ 	wrlp(mp, PORT_CONFIG, port_config);
+ }
+ 
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index a2ff9cb..6714a9d 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -4365,6 +4365,22 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
+ 		goto err_out;
+ 	}
+ 
++	/* Get configuration information
++	 * Note: only regular PCI config access once to test for HW issues
++	 *       other PCI access through shared memory for speed and to
++	 *	 avoid MMCONFIG problems.
++	 */
++	err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
++	if (err) {
++		dev_err(&pdev->dev, "PCI read config failed\n");
++		goto err_out;
++	}
++
++	if (~reg == 0) {
++		dev_err(&pdev->dev, "PCI configuration read error\n");
++		goto err_out;
++	}
++
+ 	err = pci_request_regions(pdev, DRV_NAME);
+ 	if (err) {
+ 		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+@@ -4390,21 +4406,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
+ 		}
+ 	}
+ 
+-	/* Get configuration information
+-	 * Note: only regular PCI config access once to test for HW issues
+-	 *       other PCI access through shared memory for speed and to
+-	 *	 avoid MMCONFIG problems.
+-	 */
+-	err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+-	if (err) {
+-		dev_err(&pdev->dev, "PCI read config failed\n");
+-		goto err_out_free_regions;
+-	}
+-
+-	/* size of available VPD, only impact sysfs */
+-	err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8));
+-	if (err)
+-		dev_warn(&pdev->dev, "Can't set VPD size\n");
+ 
+ #ifdef __BIG_ENDIAN
+ 	/* The sk98lin vendor driver uses hardware byte swapping but
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 735bf41..1be6a6b 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1275,21 +1275,22 @@ static int tun_chr_open(struct inode *inode, struct file * file)
+ static int tun_chr_close(struct inode *inode, struct file *file)
+ {
+ 	struct tun_file *tfile = file->private_data;
+-	struct tun_struct *tun = __tun_get(tfile);
++	struct tun_struct *tun;
+ 
+ 
++	rtnl_lock();
++	tun = __tun_get(tfile);
+ 	if (tun) {
+ 		DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
+ 
+-		rtnl_lock();
+ 		__tun_detach(tun);
+ 
+ 		/* If desireable, unregister the netdevice. */
+ 		if (!(tun->flags & TUN_PERSIST))
+ 			unregister_netdevice(tun->dev);
+ 
+-		rtnl_unlock();
+ 	}
++	rtnl_unlock();
+ 
+ 	tun = tfile->tun;
+ 	if (tun)
+diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
+index 2138535..73acbd2 100644
+--- a/drivers/net/usb/pegasus.c
++++ b/drivers/net/usb/pegasus.c
+@@ -297,7 +297,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)
+ 
+ 	pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
+ 	pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS;
+-	pegasus->dr.wValue = 0;
++	pegasus->dr.wValue = cpu_to_le16(0);
+ 	pegasus->dr.wIndex = cpu_to_le16(EthCtrl0);
+ 	pegasus->dr.wLength = cpu_to_le16(3);
+ 	pegasus->ctrl_urb->transfer_buffer_length = 3;
+@@ -446,11 +446,12 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
+ 	int i;
+ 	__u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
+ 	int ret;
++	__le16 le_data = cpu_to_le16(data);
+ 
+ 	set_registers(pegasus, EpromOffset, 4, d);
+ 	enable_eprom_write(pegasus);
+ 	set_register(pegasus, EpromOffset, index);
+-	set_registers(pegasus, EpromData, 2, &data);
++	set_registers(pegasus, EpromData, 2, &le_data);
+ 	set_register(pegasus, EpromCtrl, EPROM_WRITE);
+ 
+ 	for (i = 0; i < REG_TIMEOUT; i++) {
+@@ -923,29 +924,32 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
+ 
+ static inline void disable_net_traffic(pegasus_t * pegasus)
+ {
+-	int tmp = 0;
++	__le16 tmp = cpu_to_le16(0);
+ 
+-	set_registers(pegasus, EthCtrl0, 2, &tmp);
++	set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp);
+ }
+ 
+ static inline void get_interrupt_interval(pegasus_t * pegasus)
+ {
+-	__u8 data[2];
++	u16 data;
++	u8 interval;
+ 
+-	read_eprom_word(pegasus, 4, (__u16 *) data);
++	read_eprom_word(pegasus, 4, &data);
++	interval = data >> 8;
+ 	if (pegasus->usb->speed != USB_SPEED_HIGH) {
+-		if (data[1] < 0x80) {
++		if (interval < 0x80) {
+ 			if (netif_msg_timer(pegasus))
+ 				dev_info(&pegasus->intf->dev, "intr interval "
+ 					"changed from %ums to %ums\n",
+-					data[1], 0x80);
+-			data[1] = 0x80;
++					interval, 0x80);
++			interval = 0x80;
++			data = (data & 0x00FF) | ((u16)interval << 8);
+ #ifdef PEGASUS_WRITE_EEPROM
+-			write_eprom_word(pegasus, 4, *(__u16 *) data);
++			write_eprom_word(pegasus, 4, data);
+ #endif
+ 		}
+ 	}
+-	pegasus->intr_interval = data[1];
++	pegasus->intr_interval = interval;
+ }
+ 
+ static void set_carrier(struct net_device *net)
+@@ -1299,7 +1303,8 @@ static int pegasus_blacklisted(struct usb_device *udev)
+ 	/* Special quirk to keep the driver from handling the Belkin Bluetooth
+ 	 * dongle which happens to have the same ID.
+ 	 */
+-	if ((udd->idVendor == VENDOR_BELKIN && udd->idProduct == 0x0121) &&
++	if ((udd->idVendor == cpu_to_le16(VENDOR_BELKIN)) &&
++	    (udd->idProduct == cpu_to_le16(0x0121)) &&
+ 	    (udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) &&
+ 	    (udd->bDeviceProtocol == 1))
+ 		return 1;
+diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
+index 754a4b1..b2816ad 100644
+--- a/drivers/net/via-velocity.c
++++ b/drivers/net/via-velocity.c
+@@ -1845,7 +1845,7 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_
+ 	 */
+ 	if (tdinfo->skb_dma) {
+ 
+-		pktlen = (skb->len > ETH_ZLEN ? : ETH_ZLEN);
++		pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
+ 		for (i = 0; i < tdinfo->nskb_dma; i++) {
+ #ifdef VELOCITY_ZERO_COPY_SUPPORT
+ 			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], le16_to_cpu(td->tdesc1.len), PCI_DMA_TODEVICE);
+diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
+index 32df27a..409f022 100644
+--- a/drivers/net/wireless/ath5k/base.c
++++ b/drivers/net/wireless/ath5k/base.c
+@@ -685,6 +685,13 @@ ath5k_pci_resume(struct pci_dev *pdev)
+ 	if (err)
+ 		return err;
+ 
++	/*
++	 * Suspend/Resume resets the PCI configuration space, so we have to
++	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
++	 * PCI Tx retries from interfering with C3 CPU state
++	 */
++	pci_write_config_byte(pdev, 0x41, 0);
++
+ 	err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+ 	if (err) {
+ 		ATH5K_ERR(sc, "request_irq failed\n");
+diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
+index e2d62e9..2117074 100644
+--- a/drivers/net/wireless/ath9k/calib.c
++++ b/drivers/net/wireless/ath9k/calib.c
+@@ -284,8 +284,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
+ 		return true;
+ 	case ADC_GAIN_CAL:
+ 	case ADC_DC_CAL:
+-		if (conf->channel->band == IEEE80211_BAND_5GHZ &&
+-		  conf_is_ht20(conf))
++		if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
++		      conf_is_ht20(conf)))
+ 			return true;
+ 		break;
+ 	}
+@@ -883,7 +883,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+ {
+ 	REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+-	if (chan->channelFlags & CHANNEL_HT20) {
++	if (IS_CHAN_HT20(chan)) {
+ 		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+ 		REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+ 		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+@@ -919,83 +919,66 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+ 	return true;
+ }
+ 
+-bool ath9k_hw_init_cal(struct ath_hw *ah,
+-		       struct ath9k_channel *chan)
++bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+ {
+ 	if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+ 		if (!ar9285_clc(ah, chan))
+ 			return false;
+-	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
+-		REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+-		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+-		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
++	} else {
++		if (AR_SREV_9280_10_OR_LATER(ah)) {
++			REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
++			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
++		}
+ 
+-		/* Kick off the cal */
++		/* Calibrate the AGC */
+ 		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+-				REG_READ(ah, AR_PHY_AGC_CONTROL) |
+-				AR_PHY_AGC_CONTROL_CAL);
++			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
++			  AR_PHY_AGC_CONTROL_CAL);
+ 
+-		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+-					AR_PHY_AGC_CONTROL_CAL, 0,
+-					AH_WAIT_TIMEOUT)) {
++		/* Poll for offset calibration complete */
++		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
++				   0, AH_WAIT_TIMEOUT)) {
+ 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+ 				"offset calibration failed to complete in 1ms; "
+ 				"noisy environment?\n");
+ 			return false;
+ 		}
+ 
+-		REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+-		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+-		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+-	}
+-
+-	/* Calibrate the AGC */
+-	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+-			REG_READ(ah, AR_PHY_AGC_CONTROL) |
+-			AR_PHY_AGC_CONTROL_CAL);
+-
+-	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+-				0, AH_WAIT_TIMEOUT)) {
+-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+-			"offset calibration failed to complete in 1ms; "
+-			"noisy environment?\n");
+-		return false;
+-	}
+-
+-	if (AR_SREV_9280_10_OR_LATER(ah)) {
+-		REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+-		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
++		if (AR_SREV_9280_10_OR_LATER(ah)) {
++			REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
++			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
++		}
+ 	}
+ 
+ 	/* Do PA Calibration */
+ 	if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ 		ath9k_hw_9285_pa_cal(ah);
+ 
+-	/* Do NF Calibration */
++	/* Do NF Calibration after DC offset and other calibrations */
+ 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+-			REG_READ(ah, AR_PHY_AGC_CONTROL) |
+-			AR_PHY_AGC_CONTROL_NF);
++		  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
+ 
+ 	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+ 
++	/* Enable IQ, ADC Gain and ADC DC offset CALs */
+ 	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
+ 		if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+ 			INIT_CAL(&ah->adcgain_caldata);
+ 			INSERT_CAL(ah, &ah->adcgain_caldata);
+ 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+-					"enabling ADC Gain Calibration.\n");
++				"enabling ADC Gain Calibration.\n");
+ 		}
+ 		if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
+ 			INIT_CAL(&ah->adcdc_caldata);
+ 			INSERT_CAL(ah, &ah->adcdc_caldata);
+ 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+-					"enabling ADC DC Calibration.\n");
++				"enabling ADC DC Calibration.\n");
+ 		}
+ 		if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+ 			INIT_CAL(&ah->iq_caldata);
+ 			INSERT_CAL(ah, &ah->iq_caldata);
+ 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+-					"enabling IQ Calibration.\n");
++				"enabling IQ Calibration.\n");
+ 		}
+ 
+ 		ah->cal_list_curr = ah->cal_list;
+diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
+index 13d4e67..bb5312f 100644
+--- a/drivers/net/wireless/ath9k/main.c
++++ b/drivers/net/wireless/ath9k/main.c
+@@ -408,6 +408,18 @@ set_timer:
+ 	mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+ }
+ 
++static void ath_start_ani(struct ath_softc *sc)
++{
++	unsigned long timestamp = jiffies_to_msecs(jiffies);
++
++	sc->ani.longcal_timer = timestamp;
++	sc->ani.shortcal_timer = timestamp;
++	sc->ani.checkani_timer = timestamp;
++
++	mod_timer(&sc->ani.timer,
++		  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
++}
++
+ /*
+  * Update tx/rx chainmask. For legacy association,
+  * hard code chainmask to 1x1, for 11n association, use
+@@ -920,9 +932,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
+ 		sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
+ 		sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
+ 
+-		/* Start ANI */
+-		mod_timer(&sc->ani.timer,
+-			  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
++		ath_start_ani(sc);
+ 	} else {
+ 		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
+ 		sc->curaid = 0;
+@@ -1416,7 +1426,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
+ 	for (i = 0; i < sc->keymax; i++)
+ 		ath9k_hw_keyreset(ah, (u16) i);
+ 
+-	if (ath9k_regd_init(sc->sc_ah))
++	error = ath9k_regd_init(sc->sc_ah);
++	if (error)
+ 		goto bad;
+ 
+ 	/* default to MONITOR mode */
+@@ -2270,12 +2281,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
+ 
+ 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+ 
+-	if (conf->type == NL80211_IFTYPE_AP) {
+-		/* TODO: is this a suitable place to start ANI for AP mode? */
+-		/* Start ANI */
+-		mod_timer(&sc->ani.timer,
+-			  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+-	}
++	if (conf->type == NL80211_IFTYPE_AP)
++		ath_start_ani(sc);
+ 
+ out:
+ 	mutex_unlock(&sc->mutex);
+@@ -2771,6 +2778,7 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
+ 	mutex_lock(&sc->mutex);
+ 	aphy->state = ATH_WIPHY_ACTIVE;
+ 	sc->sc_flags &= ~SC_OP_SCANNING;
++	sc->sc_flags |= SC_OP_FULL_RESET;
+ 	mutex_unlock(&sc->mutex);
+ }
+ 
+diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
+index 168411d..4affb49 100644
+--- a/drivers/net/wireless/ath9k/pci.c
++++ b/drivers/net/wireless/ath9k/pci.c
+@@ -87,6 +87,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	struct ath_softc *sc;
+ 	struct ieee80211_hw *hw;
+ 	u8 csz;
++	u32 val;
+ 	int ret = 0;
+ 	struct ath_hw *ah;
+ 
+@@ -133,6 +134,14 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 
+ 	pci_set_master(pdev);
+ 
++	/*
++	 * Disable the RETRY_TIMEOUT register (0x41) to keep
++	 * PCI Tx retries from interfering with C3 CPU state.
++	 */
++	pci_read_config_dword(pdev, 0x40, &val);
++	if ((val & 0x0000ff00) != 0)
++		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
++
+ 	ret = pci_request_region(pdev, 0, "ath9k");
+ 	if (ret) {
+ 		dev_err(&pdev->dev, "PCI memory region reserve error\n");
+@@ -244,12 +253,21 @@ static int ath_pci_resume(struct pci_dev *pdev)
+ 	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ 	struct ath_wiphy *aphy = hw->priv;
+ 	struct ath_softc *sc = aphy->sc;
++	u32 val;
+ 	int err;
+ 
+ 	err = pci_enable_device(pdev);
+ 	if (err)
+ 		return err;
+ 	pci_restore_state(pdev);
++	/*
++	 * Suspend/Resume resets the PCI configuration space, so we have to
++	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
++	 * PCI Tx retries from interfering with C3 CPU state
++	 */
++	pci_read_config_dword(pdev, 0x40, &val);
++	if ((val & 0x0000ff00) != 0)
++		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+ 
+ 	/* Enable LED */
+ 	ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
+index 4ca6251..5256d24 100644
+--- a/drivers/net/wireless/ath9k/regd.c
++++ b/drivers/net/wireless/ath9k/regd.c
+@@ -439,7 +439,7 @@ int ath9k_regd_init(struct ath_hw *ah)
+ 	u16 regdmn;
+ 
+ 	if (!ath9k_regd_is_eeprom_valid(ah)) {
+-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
++		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ 			"Invalid EEPROM contents\n");
+ 		return -EINVAL;
+ 	}
+diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
+index 689bdbf..c92f442 100644
+--- a/drivers/net/wireless/ath9k/xmit.c
++++ b/drivers/net/wireless/ath9k/xmit.c
+@@ -1573,8 +1573,9 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+ 					   skb->len, DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+ 		bf->bf_mpdu = NULL;
+-		DPRINTF(sc, ATH_DBG_CONFIG,
+-			"dma_mapping_error() on TX\n");
++		kfree(tx_info_priv);
++		tx_info->rate_driver_data[0] = NULL;
++		DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on TX\n");
+ 		return -ENOMEM;
+ 	}
+ 
+diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
+index 4e63cc9..3d3c9c0 100644
+--- a/drivers/parport/parport_pc.c
++++ b/drivers/parport/parport_pc.c
+@@ -1413,11 +1413,13 @@ static void __devinit decode_smsc(int efer, int key, int devid, int devrev)
+ 
+ static void __devinit winbond_check(int io, int key)
+ {
+-	int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
++	int origval, devid, devrev, oldid, x_devid, x_devrev, x_oldid;
+ 
+ 	if (!request_region(io, 3, __func__))
+ 		return;
+ 
++	origval = inb(io); /* Save original value */
++
+ 	/* First probe without key */
+ 	outb(0x20,io);
+ 	x_devid=inb(io+1);
+@@ -1437,6 +1439,8 @@ static void __devinit winbond_check(int io, int key)
+ 	oldid=inb(io+1);
+ 	outb(0xaa,io);    /* Magic Seal */
+ 
++	outb(origval, io); /* in case we poked some entirely different hardware */
++
+ 	if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
+ 		goto out; /* protection against false positives */
+ 
+@@ -1447,11 +1451,15 @@ out:
+ 
+ static void __devinit winbond_check2(int io,int key)
+ {
+-        int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
++	int origval[3], devid, devrev, oldid, x_devid, x_devrev, x_oldid;
+ 
+ 	if (!request_region(io, 3, __func__))
+ 		return;
+ 
++	origval[0] = inb(io); /* Save original values */
++	origval[1] = inb(io + 1);
++	origval[2] = inb(io + 2);
++
+ 	/* First probe without the key */
+ 	outb(0x20,io+2);
+ 	x_devid=inb(io+2);
+@@ -1470,6 +1478,10 @@ static void __devinit winbond_check2(int io,int key)
+         oldid=inb(io+2);
+         outb(0xaa,io);    /* Magic Seal */
+ 
++	outb(origval[0], io); /* in case we poked some entirely different hardware */
++	outb(origval[1], io + 1);
++	outb(origval[2], io + 2);
++
+ 	if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
+ 		goto out; /* protection against false positives */
+ 
+@@ -1480,11 +1492,13 @@ out:
+ 
+ static void __devinit smsc_check(int io, int key)
+ {
+-        int id,rev,oldid,oldrev,x_id,x_rev,x_oldid,x_oldrev;
++	int origval, id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;
+ 
+ 	if (!request_region(io, 3, __func__))
+ 		return;
+ 
++	origval = inb(io); /* Save original value */
++
+ 	/* First probe without the key */
+ 	outb(0x0d,io);
+ 	x_oldid=inb(io+1);
+@@ -1508,6 +1522,8 @@ static void __devinit smsc_check(int io, int key)
+ 	rev=inb(io+1);
+         outb(0xaa,io);    /* Magic Seal */
+ 
++	outb(origval, io); /* in case we poked some entirely different hardware */
++
+ 	if ((x_id == id) && (x_oldrev == oldrev) &&
+ 	    (x_oldid == oldid) && (x_rev == rev))
+ 		goto out; /* protection against false positives */
+@@ -1544,11 +1560,12 @@ static void __devinit detect_and_report_smsc (void)
+ static void __devinit detect_and_report_it87(void)
+ {
+ 	u16 dev;
+-	u8 r;
++	u8 origval, r;
+ 	if (verbose_probing)
+ 		printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
+-	if (!request_region(0x2e, 1, __func__))
++	if (!request_region(0x2e, 2, __func__))
+ 		return;
++	origval = inb(0x2e);		/* Save original value */
+ 	outb(0x87, 0x2e);
+ 	outb(0x01, 0x2e);
+ 	outb(0x55, 0x2e);
+@@ -1568,8 +1585,10 @@ static void __devinit detect_and_report_it87(void)
+ 		outb(r | 8, 0x2F);
+ 		outb(0x02, 0x2E);	/* Lock */
+ 		outb(0x02, 0x2F);
++	} else {
++		outb(origval, 0x2e);	/* Oops, sorry to disturb */
+ 	}
+-	release_region(0x2e, 1);
++	release_region(0x2e, 2);
+ }
+ #endif /* CONFIG_PARPORT_PC_SUPERIO */
+ 
+@@ -2193,6 +2212,9 @@ struct parport *parport_pc_probe_port(unsigned long int base,
+ 		if (IS_ERR(pdev))
+ 			return NULL;
+ 		dev = &pdev->dev;
++
++		dev->coherent_dma_mask = DMA_BIT_MASK(24);
++		dev->dma_mask = &dev->coherent_dma_mask;
+ 	}
+ 
+ 	ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 1a91bf9..440f4fb 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -480,6 +480,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
+ 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ 		pmcsr |= state;
+ 		break;
++	case PCI_D3hot:
++	case PCI_D3cold:
+ 	case PCI_UNKNOWN: /* Boot-up */
+ 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
+ 		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+@@ -1282,15 +1284,14 @@ pci_power_t pci_target_state(struct pci_dev *dev)
+ 		default:
+ 			target_state = state;
+ 		}
++	} else if (!dev->pm_cap) {
++		target_state = PCI_D0;
+ 	} else if (device_may_wakeup(&dev->dev)) {
+ 		/*
+ 		 * Find the deepest state from which the device can generate
+ 		 * wake-up events, make it the target state and enable device
+ 		 * to generate PME#.
+ 		 */
+-		if (!dev->pm_cap)
+-			return PCI_POWER_ERROR;
+-
+ 		if (dev->pme_support) {
+ 			while (target_state
+ 			      && !(dev->pme_support & (1 << target_state)))
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index b0367f1..777b2c7 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -638,6 +638,10 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
+ 	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+ 		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+ 		return;
++	/* VIA has a strange chipset, root port is under a bridge */
++	if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
++		pdev->bus->self)
++		return;
+ 	down_read(&pci_bus_sem);
+ 	if (list_empty(&pdev->subordinate->devices))
+ 		goto out;
+diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
+index 34760f8..00856ba 100644
+--- a/drivers/scsi/qla2xxx/qla_dbg.c
++++ b/drivers/scsi/qla2xxx/qla_dbg.c
+@@ -218,7 +218,7 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
+ 
+ static int
+ qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
+-    uint16_t ram_words, void **nxt)
++    uint32_t ram_words, void **nxt)
+ {
+ 	int rval;
+ 	uint32_t cnt, stat, timer, words, idx;
+diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
+index ffa70d1..e9e1865 100644
+--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
++++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
+@@ -2312,8 +2312,9 @@ static void sym_int_par (struct sym_hcb *np, u_short sist)
+ 	int phase	= cmd & 7;
+ 	struct sym_ccb *cp	= sym_ccb_from_dsa(np, dsa);
+ 
+-	printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
+-		sym_name(np), hsts, dbc, sbcl);
++	if (printk_ratelimit())
++		printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
++			sym_name(np), hsts, dbc, sbcl);
+ 
+ 	/*
+ 	 *  Check that the chip is connected to the SCSI BUS.
+diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
+index d86123e..a543acf 100644
+--- a/drivers/serial/bfin_5xx.c
++++ b/drivers/serial/bfin_5xx.c
+@@ -38,6 +38,10 @@
+ #include <asm/cacheflush.h>
+ #endif
+ 
++#ifdef CONFIG_SERIAL_BFIN_MODULE
++# undef CONFIG_EARLY_PRINTK
++#endif
++
+ /* UART name and device definitions */
+ #define BFIN_SERIAL_NAME	"ttyBF"
+ #define BFIN_SERIAL_MAJOR	204
+@@ -1058,6 +1062,7 @@ static void __init bfin_serial_init_ports(void)
+ 	bfin_serial_hw_init();
+ 
+ 	for (i = 0; i < nr_active_ports; i++) {
++		spin_lock_init(&bfin_serial_ports[i].port.lock);
+ 		bfin_serial_ports[i].port.uartclk   = get_sclk();
+ 		bfin_serial_ports[i].port.fifosize  = BFIN_UART_TX_FIFO_SIZE;
+ 		bfin_serial_ports[i].port.ops       = &bfin_serial_pops;
+diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
+index f4573a9..a32ccb4 100644
+--- a/drivers/spi/spi_mpc83xx.c
++++ b/drivers/spi/spi_mpc83xx.c
+@@ -711,12 +711,12 @@ static int of_mpc83xx_spi_get_chipselects(struct device *dev)
+ 		return 0;
+ 	}
+ 
+-	pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL);
++	pinfo->gpios = kmalloc(ngpios * sizeof(*pinfo->gpios), GFP_KERNEL);
+ 	if (!pinfo->gpios)
+ 		return -ENOMEM;
+-	memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios));
++	memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios));
+ 
+-	pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags),
++	pinfo->alow_flags = kzalloc(ngpios * sizeof(*pinfo->alow_flags),
+ 				    GFP_KERNEL);
+ 	if (!pinfo->alow_flags) {
+ 		ret = -ENOMEM;
+diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c
+index 9c62f78..39d0926 100644
+--- a/drivers/staging/uc2322/aten2011.c
++++ b/drivers/staging/uc2322/aten2011.c
+@@ -2336,7 +2336,7 @@ static int ATEN2011_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void ATEN2011_shutdown(struct usb_serial *serial)
++static void ATEN2011_release(struct usb_serial *serial)
+ {
+ 	int i;
+ 	struct ATENINTL_port *ATEN2011_port;
+@@ -2382,7 +2382,7 @@ static struct usb_serial_driver aten_serial_driver = {
+ 	.tiocmget =		ATEN2011_tiocmget,
+ 	.tiocmset =		ATEN2011_tiocmset,
+ 	.attach =		ATEN2011_startup,
+-	.shutdown =		ATEN2011_shutdown,
++	.release =		ATEN2011_release,
+ 	.read_bulk_callback =	ATEN2011_bulk_in_callback,
+ 	.read_int_callback =	ATEN2011_interrupt_callback,
+ };
+diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
+index c40a9b2..3703789 100644
+--- a/drivers/usb/class/usbtmc.c
++++ b/drivers/usb/class/usbtmc.c
+@@ -927,21 +927,27 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ 	switch (cmd) {
+ 	case USBTMC_IOCTL_CLEAR_OUT_HALT:
+ 		retval = usbtmc_ioctl_clear_out_halt(data);
++		break;
+ 
+ 	case USBTMC_IOCTL_CLEAR_IN_HALT:
+ 		retval = usbtmc_ioctl_clear_in_halt(data);
++		break;
+ 
+ 	case USBTMC_IOCTL_INDICATOR_PULSE:
+ 		retval = usbtmc_ioctl_indicator_pulse(data);
++		break;
+ 
+ 	case USBTMC_IOCTL_CLEAR:
+ 		retval = usbtmc_ioctl_clear(data);
++		break;
+ 
+ 	case USBTMC_IOCTL_ABORT_BULK_OUT:
+ 		retval = usbtmc_ioctl_abort_bulk_out(data);
++		break;
+ 
+ 	case USBTMC_IOCTL_ABORT_BULK_IN:
+ 		retval = usbtmc_ioctl_abort_bulk_in(data);
++		break;
+ 	}
+ 
+ 	mutex_unlock(&data->io_mutex);
+diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
+index 6d106e7..2cbfab3 100644
+--- a/drivers/usb/serial/aircable.c
++++ b/drivers/usb/serial/aircable.c
+@@ -364,7 +364,7 @@ static int aircable_attach(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void aircable_shutdown(struct usb_serial *serial)
++static void aircable_release(struct usb_serial *serial)
+ {
+ 
+ 	struct usb_serial_port *port = serial->port[0];
+@@ -375,7 +375,6 @@ static void aircable_shutdown(struct usb_serial *serial)
+ 	if (priv) {
+ 		serial_buf_free(priv->tx_buf);
+ 		serial_buf_free(priv->rx_buf);
+-		usb_set_serial_port_data(port, NULL);
+ 		kfree(priv);
+ 	}
+ }
+@@ -601,7 +600,7 @@ static struct usb_serial_driver aircable_device = {
+ 	.num_ports =		1,
+ 	.attach =		aircable_attach,
+ 	.probe =		aircable_probe,
+-	.shutdown =		aircable_shutdown,
++	.release =		aircable_release,
+ 	.write =		aircable_write,
+ 	.write_room =		aircable_write_room,
+ 	.write_bulk_callback =	aircable_write_bulk_callback,
+diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
+index b7eacad..9637228 100644
+--- a/drivers/usb/serial/belkin_sa.c
++++ b/drivers/usb/serial/belkin_sa.c
+@@ -90,7 +90,7 @@ static int debug;
+ 
+ /* function prototypes for a Belkin USB Serial Adapter F5U103 */
+ static int  belkin_sa_startup(struct usb_serial *serial);
+-static void belkin_sa_shutdown(struct usb_serial *serial);
++static void belkin_sa_release(struct usb_serial *serial);
+ static int  belkin_sa_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static void belkin_sa_close(struct tty_struct *tty,
+@@ -143,7 +143,7 @@ static struct usb_serial_driver belkin_device = {
+ 	.tiocmget =		belkin_sa_tiocmget,
+ 	.tiocmset =		belkin_sa_tiocmset,
+ 	.attach =		belkin_sa_startup,
+-	.shutdown =		belkin_sa_shutdown,
++	.release =		belkin_sa_release,
+ };
+ 
+ 
+@@ -198,14 +198,13 @@ static int belkin_sa_startup(struct usb_serial *serial)
+ }
+ 
+ 
+-static void belkin_sa_shutdown(struct usb_serial *serial)
++static void belkin_sa_release(struct usb_serial *serial)
+ {
+ 	struct belkin_sa_private *priv;
+ 	int i;
+ 
+ 	dbg("%s", __func__);
+ 
+-	/* stop reads and writes on all ports */
+ 	for (i = 0; i < serial->num_ports; ++i) {
+ 		/* My special items, the standard routines free my urbs */
+ 		priv = usb_get_serial_port_data(serial->port[i]);
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index e8d5133..cf5093f 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -51,7 +51,7 @@ static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *,
+ 		unsigned int, unsigned int);
+ static void cp2101_break_ctl(struct tty_struct *, int);
+ static int cp2101_startup(struct usb_serial *);
+-static void cp2101_shutdown(struct usb_serial *);
++static void cp2101_disconnect(struct usb_serial *);
+ 
+ static int debug;
+ 
+@@ -131,7 +131,7 @@ static struct usb_serial_driver cp2101_device = {
+ 	.tiocmget 		= cp2101_tiocmget,
+ 	.tiocmset		= cp2101_tiocmset,
+ 	.attach			= cp2101_startup,
+-	.shutdown		= cp2101_shutdown,
++	.disconnect		= cp2101_disconnect,
+ };
+ 
+ /* Config request types */
+@@ -773,7 +773,7 @@ static int cp2101_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void cp2101_shutdown(struct usb_serial *serial)
++static void cp2101_disconnect(struct usb_serial *serial)
+ {
+ 	int i;
+ 
+diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
+index dd501bb..49cf9ee 100644
+--- a/drivers/usb/serial/cyberjack.c
++++ b/drivers/usb/serial/cyberjack.c
+@@ -58,7 +58,8 @@ static int debug;
+ 
+ /* Function prototypes */
+ static int cyberjack_startup(struct usb_serial *serial);
+-static void cyberjack_shutdown(struct usb_serial *serial);
++static void cyberjack_disconnect(struct usb_serial *serial);
++static void cyberjack_release(struct usb_serial *serial);
+ static int  cyberjack_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static void cyberjack_close(struct tty_struct *tty,
+@@ -95,7 +96,8 @@ static struct usb_serial_driver cyberjack_device = {
+ 	.id_table =		id_table,
+ 	.num_ports =		1,
+ 	.attach =		cyberjack_startup,
+-	.shutdown =		cyberjack_shutdown,
++	.disconnect =		cyberjack_disconnect,
++	.release =		cyberjack_release,
+ 	.open =			cyberjack_open,
+ 	.close =		cyberjack_close,
+ 	.write =		cyberjack_write,
+@@ -149,17 +151,25 @@ static int cyberjack_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void cyberjack_shutdown(struct usb_serial *serial)
++static void cyberjack_disconnect(struct usb_serial *serial)
+ {
+ 	int i;
+ 
+ 	dbg("%s", __func__);
+ 
+-	for (i = 0; i < serial->num_ports; ++i) {
++	for (i = 0; i < serial->num_ports; ++i)
+ 		usb_kill_urb(serial->port[i]->interrupt_in_urb);
++}
++
++static void cyberjack_release(struct usb_serial *serial)
++{
++	int i;
++
++	dbg("%s", __func__);
++
++	for (i = 0; i < serial->num_ports; ++i) {
+ 		/* My special items, the standard routines free my urbs */
+ 		kfree(usb_get_serial_port_data(serial->port[i]));
+-		usb_set_serial_port_data(serial->port[i], NULL);
+ 	}
+ }
+ 
+diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
+index e568710..b8e6e4d 100644
+--- a/drivers/usb/serial/cypress_m8.c
++++ b/drivers/usb/serial/cypress_m8.c
+@@ -171,7 +171,7 @@ struct cypress_buf {
+ static int  cypress_earthmate_startup(struct usb_serial *serial);
+ static int  cypress_hidcom_startup(struct usb_serial *serial);
+ static int  cypress_ca42v2_startup(struct usb_serial *serial);
+-static void cypress_shutdown(struct usb_serial *serial);
++static void cypress_release(struct usb_serial *serial);
+ static int  cypress_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static void cypress_close(struct tty_struct *tty,
+@@ -215,7 +215,7 @@ static struct usb_serial_driver cypress_earthmate_device = {
+ 	.id_table =			id_table_earthmate,
+ 	.num_ports =			1,
+ 	.attach =			cypress_earthmate_startup,
+-	.shutdown =			cypress_shutdown,
++	.release =			cypress_release,
+ 	.open =				cypress_open,
+ 	.close =			cypress_close,
+ 	.write =			cypress_write,
+@@ -241,7 +241,7 @@ static struct usb_serial_driver cypress_hidcom_device = {
+ 	.id_table =			id_table_cyphidcomrs232,
+ 	.num_ports =			1,
+ 	.attach =			cypress_hidcom_startup,
+-	.shutdown =			cypress_shutdown,
++	.release =			cypress_release,
+ 	.open =				cypress_open,
+ 	.close =			cypress_close,
+ 	.write =			cypress_write,
+@@ -267,7 +267,7 @@ static struct usb_serial_driver cypress_ca42v2_device = {
+ 	.id_table =			id_table_nokiaca42v2,
+ 	.num_ports =			1,
+ 	.attach =			cypress_ca42v2_startup,
+-	.shutdown =			cypress_shutdown,
++	.release =			cypress_release,
+ 	.open =				cypress_open,
+ 	.close =			cypress_close,
+ 	.write =			cypress_write,
+@@ -613,7 +613,7 @@ static int cypress_ca42v2_startup(struct usb_serial *serial)
+ } /* cypress_ca42v2_startup */
+ 
+ 
+-static void cypress_shutdown(struct usb_serial *serial)
++static void cypress_release(struct usb_serial *serial)
+ {
+ 	struct cypress_private *priv;
+ 
+@@ -626,7 +626,6 @@ static void cypress_shutdown(struct usb_serial *serial)
+ 	if (priv) {
+ 		cypress_buf_free(priv->buf);
+ 		kfree(priv);
+-		usb_set_serial_port_data(serial->port[0], NULL);
+ 	}
+ }
+ 
+diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
+index 38ba4ea..e9373db 100644
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -460,7 +460,8 @@ static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
+ 	struct file *filp);
+ static int digi_startup_device(struct usb_serial *serial);
+ static int digi_startup(struct usb_serial *serial);
+-static void digi_shutdown(struct usb_serial *serial);
++static void digi_disconnect(struct usb_serial *serial);
++static void digi_release(struct usb_serial *serial);
+ static void digi_read_bulk_callback(struct urb *urb);
+ static int digi_read_inb_callback(struct urb *urb);
+ static int digi_read_oob_callback(struct urb *urb);
+@@ -522,7 +523,8 @@ static struct usb_serial_driver digi_acceleport_2_device = {
+ 	.tiocmget =			digi_tiocmget,
+ 	.tiocmset =			digi_tiocmset,
+ 	.attach =			digi_startup,
+-	.shutdown =			digi_shutdown,
++	.disconnect =			digi_disconnect,
++	.release =			digi_release,
+ };
+ 
+ static struct usb_serial_driver digi_acceleport_4_device = {
+@@ -548,7 +550,8 @@ static struct usb_serial_driver digi_acceleport_4_device = {
+ 	.tiocmget =			digi_tiocmget,
+ 	.tiocmset =			digi_tiocmset,
+ 	.attach =			digi_startup,
+-	.shutdown =			digi_shutdown,
++	.disconnect =			digi_disconnect,
++	.release =			digi_release,
+ };
+ 
+ 
+@@ -1589,16 +1592,23 @@ static int digi_startup(struct usb_serial *serial)
+ }
+ 
+ 
+-static void digi_shutdown(struct usb_serial *serial)
++static void digi_disconnect(struct usb_serial *serial)
+ {
+ 	int i;
+-	dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt());
++	dbg("digi_disconnect: TOP, in_interrupt()=%ld", in_interrupt());
+ 
+ 	/* stop reads and writes on all ports */
+ 	for (i = 0; i < serial->type->num_ports + 1; i++) {
+ 		usb_kill_urb(serial->port[i]->read_urb);
+ 		usb_kill_urb(serial->port[i]->write_urb);
+ 	}
++}
++
++
++static void digi_release(struct usb_serial *serial)
++{
++	int i;
++	dbg("digi_release: TOP, in_interrupt()=%ld", in_interrupt());
+ 
+ 	/* free the private data structures for all ports */
+ 	/* number of regular ports + 1 for the out-of-band port */
+diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
+index c709ec4..b0d678c 100644
+--- a/drivers/usb/serial/empeg.c
++++ b/drivers/usb/serial/empeg.c
+@@ -91,7 +91,6 @@ static int  empeg_chars_in_buffer(struct tty_struct *tty);
+ static void empeg_throttle(struct tty_struct *tty);
+ static void empeg_unthrottle(struct tty_struct *tty);
+ static int  empeg_startup(struct usb_serial *serial);
+-static void empeg_shutdown(struct usb_serial *serial);
+ static void empeg_set_termios(struct tty_struct *tty,
+ 		struct usb_serial_port *port, struct ktermios *old_termios);
+ static void empeg_write_bulk_callback(struct urb *urb);
+@@ -125,7 +124,6 @@ static struct usb_serial_driver empeg_device = {
+ 	.throttle =		empeg_throttle,
+ 	.unthrottle =		empeg_unthrottle,
+ 	.attach =		empeg_startup,
+-	.shutdown =		empeg_shutdown,
+ 	.set_termios =		empeg_set_termios,
+ 	.write =		empeg_write,
+ 	.write_room =		empeg_write_room,
+@@ -429,12 +427,6 @@ static int  empeg_startup(struct usb_serial *serial)
+ }
+ 
+ 
+-static void empeg_shutdown(struct usb_serial *serial)
+-{
+-	dbg("%s", __func__);
+-}
+-
+-
+ static void empeg_set_termios(struct tty_struct *tty,
+ 		struct usb_serial_port *port, struct ktermios *old_termios)
+ {
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index d9fcdae..9722512 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -714,7 +714,6 @@ static const char *ftdi_chip_name[] = {
+ /* function prototypes for a FTDI serial converter */
+ static int  ftdi_sio_probe(struct usb_serial *serial,
+ 					const struct usb_device_id *id);
+-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);
+ static int  ftdi_open(struct tty_struct *tty,
+@@ -770,7 +769,6 @@ static struct usb_serial_driver ftdi_sio_device = {
+ 	.ioctl =		ftdi_ioctl,
+ 	.set_termios =		ftdi_set_termios,
+ 	.break_ctl =		ftdi_break_ctl,
+-	.shutdown =		ftdi_shutdown,
+ };
+ 
+ 
+@@ -1460,18 +1458,6 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
+- *   it is called when the usb device is disconnected
+- *
+- *   usbserial:usb_serial_disconnect
+- *      calls __serial_close for each open of the port
+- *      shutdown is called then (ie ftdi_shutdown)
+- */
+-static void ftdi_shutdown(struct usb_serial *serial)
+-{
+-	dbg("%s", __func__);
+-}
+-
+ static void ftdi_sio_priv_release(struct kref *k)
+ {
+ 	struct ftdi_private *priv = container_of(k, struct ftdi_private, kref);
+diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
+index 586d30f..ed8bd90 100644
+--- a/drivers/usb/serial/garmin_gps.c
++++ b/drivers/usb/serial/garmin_gps.c
+@@ -1528,7 +1528,7 @@ static int garmin_attach(struct usb_serial *serial)
+ }
+ 
+ 
+-static void garmin_shutdown(struct usb_serial *serial)
++static void garmin_disconnect(struct usb_serial *serial)
+ {
+ 	struct usb_serial_port *port = serial->port[0];
+ 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
+@@ -1537,8 +1537,17 @@ static void garmin_shutdown(struct usb_serial *serial)
+ 
+ 	usb_kill_urb(port->interrupt_in_urb);
+ 	del_timer_sync(&garmin_data_p->timer);
++}
++
++
++static void garmin_release(struct usb_serial *serial)
++{
++	struct usb_serial_port *port = serial->port[0];
++	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
++
++	dbg("%s", __func__);
++
+ 	kfree(garmin_data_p);
+-	usb_set_serial_port_data(port, NULL);
+ }
+ 
+ 
+@@ -1557,7 +1566,8 @@ static struct usb_serial_driver garmin_device = {
+ 	.throttle            = garmin_throttle,
+ 	.unthrottle          = garmin_unthrottle,
+ 	.attach              = garmin_attach,
+-	.shutdown            = garmin_shutdown,
++	.disconnect          = garmin_disconnect,
++	.release             = garmin_release,
+ 	.write               = garmin_write,
+ 	.write_room          = garmin_write_room,
+ 	.write_bulk_callback = garmin_write_bulk_callback,
+diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
+index 4cec990..ef29788 100644
+--- a/drivers/usb/serial/generic.c
++++ b/drivers/usb/serial/generic.c
+@@ -63,7 +63,8 @@ struct usb_serial_driver usb_serial_generic_device = {
+ 	.id_table =		generic_device_ids,
+ 	.usb_driver = 		&generic_driver,
+ 	.num_ports =		1,
+-	.shutdown =		usb_serial_generic_shutdown,
++	.disconnect =		usb_serial_generic_disconnect,
++	.release =		usb_serial_generic_release,
+ 	.throttle =		usb_serial_generic_throttle,
+ 	.unthrottle =		usb_serial_generic_unthrottle,
+ 	.resume =		usb_serial_generic_resume,
+@@ -413,7 +414,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
+ 	}
+ }
+ 
+-void usb_serial_generic_shutdown(struct usb_serial *serial)
++void usb_serial_generic_disconnect(struct usb_serial *serial)
+ {
+ 	int i;
+ 
+@@ -424,3 +425,7 @@ void usb_serial_generic_shutdown(struct usb_serial *serial)
+ 		generic_cleanup(serial->port[i]);
+ }
+ 
++void usb_serial_generic_release(struct usb_serial *serial)
++{
++	dbg("%s", __func__);
++}
+diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
+index fb4a73d..fc509bb 100644
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -225,7 +225,8 @@ static int  edge_tiocmget(struct tty_struct *tty, struct file *file);
+ static int  edge_tiocmset(struct tty_struct *tty, struct file *file,
+ 					unsigned int set, unsigned int clear);
+ static int  edge_startup(struct usb_serial *serial);
+-static void edge_shutdown(struct usb_serial *serial);
++static void edge_disconnect(struct usb_serial *serial);
++static void edge_release(struct usb_serial *serial);
+ 
+ #include "io_tables.h"	/* all of the devices that this driver supports */
+ 
+@@ -3195,21 +3196,16 @@ static int edge_startup(struct usb_serial *serial)
+ 
+ 
+ /****************************************************************************
+- * edge_shutdown
++ * edge_disconnect
+  *	This function is called whenever the device is removed from the usb bus.
+  ****************************************************************************/
+-static void edge_shutdown(struct usb_serial *serial)
++static void edge_disconnect(struct usb_serial *serial)
+ {
+ 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
+-	int i;
+ 
+ 	dbg("%s", __func__);
+ 
+ 	/* stop reads and writes on all ports */
+-	for (i = 0; i < serial->num_ports; ++i) {
+-		kfree(usb_get_serial_port_data(serial->port[i]));
+-		usb_set_serial_port_data(serial->port[i],  NULL);
+-	}
+ 	/* free up our endpoint stuff */
+ 	if (edge_serial->is_epic) {
+ 		usb_kill_urb(edge_serial->interrupt_read_urb);
+@@ -3220,9 +3216,24 @@ static void edge_shutdown(struct usb_serial *serial)
+ 		usb_free_urb(edge_serial->read_urb);
+ 		kfree(edge_serial->bulk_in_buffer);
+ 	}
++}
++
++
++/****************************************************************************
++ * edge_release
++ *	This function is called when the device structure is deallocated.
++ ****************************************************************************/
++static void edge_release(struct usb_serial *serial)
++{
++	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
++	int i;
++
++	dbg("%s", __func__);
++
++	for (i = 0; i < serial->num_ports; ++i)
++		kfree(usb_get_serial_port_data(serial->port[i]));
+ 
+ 	kfree(edge_serial);
+-	usb_set_serial_data(serial, NULL);
+ }
+ 
+ 
+diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
+index 7eb9d67..9241d31 100644
+--- a/drivers/usb/serial/io_tables.h
++++ b/drivers/usb/serial/io_tables.h
+@@ -117,7 +117,8 @@ static struct usb_serial_driver edgeport_2port_device = {
+ 	.throttle		= edge_throttle,
+ 	.unthrottle		= edge_unthrottle,
+ 	.attach			= edge_startup,
+-	.shutdown		= edge_shutdown,
++	.disconnect		= edge_disconnect,
++	.release		= edge_release,
+ 	.ioctl			= edge_ioctl,
+ 	.set_termios		= edge_set_termios,
+ 	.tiocmget		= edge_tiocmget,
+@@ -145,7 +146,8 @@ static struct usb_serial_driver edgeport_4port_device = {
+ 	.throttle		= edge_throttle,
+ 	.unthrottle		= edge_unthrottle,
+ 	.attach			= edge_startup,
+-	.shutdown		= edge_shutdown,
++	.disconnect		= edge_disconnect,
++	.release		= edge_release,
+ 	.ioctl			= edge_ioctl,
+ 	.set_termios		= edge_set_termios,
+ 	.tiocmget		= edge_tiocmget,
+@@ -173,7 +175,8 @@ static struct usb_serial_driver edgeport_8port_device = {
+ 	.throttle		= edge_throttle,
+ 	.unthrottle		= edge_unthrottle,
+ 	.attach			= edge_startup,
+-	.shutdown		= edge_shutdown,
++	.disconnect		= edge_disconnect,
++	.release		= edge_release,
+ 	.ioctl			= edge_ioctl,
+ 	.set_termios		= edge_set_termios,
+ 	.tiocmget		= edge_tiocmget,
+@@ -200,7 +203,8 @@ static struct usb_serial_driver epic_device = {
+ 	.throttle		= edge_throttle,
+ 	.unthrottle		= edge_unthrottle,
+ 	.attach			= edge_startup,
+-	.shutdown		= edge_shutdown,
++	.disconnect		= edge_disconnect,
++	.release		= edge_release,
+ 	.ioctl			= edge_ioctl,
+ 	.set_termios		= edge_set_termios,
+ 	.tiocmget		= edge_tiocmget,
+diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
+index 513b25e..3139246 100644
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2664,7 +2664,7 @@ cleanup:
+ 	return -ENOMEM;
+ }
+ 
+-static void edge_shutdown(struct usb_serial *serial)
++static void edge_disconnect(struct usb_serial *serial)
+ {
+ 	int i;
+ 	struct edgeport_port *edge_port;
+@@ -2674,12 +2674,22 @@ static void edge_shutdown(struct usb_serial *serial)
+ 	for (i = 0; i < serial->num_ports; ++i) {
+ 		edge_port = usb_get_serial_port_data(serial->port[i]);
+ 		edge_remove_sysfs_attrs(edge_port->port);
++	}
++}
++
++static void edge_release(struct usb_serial *serial)
++{
++	int i;
++	struct edgeport_port *edge_port;
++
++	dbg("%s", __func__);
++
++	for (i = 0; i < serial->num_ports; ++i) {
++		edge_port = usb_get_serial_port_data(serial->port[i]);
+ 		edge_buf_free(edge_port->ep_out_buf);
+ 		kfree(edge_port);
+-		usb_set_serial_port_data(serial->port[i], NULL);
+ 	}
+ 	kfree(usb_get_serial_data(serial));
+-	usb_set_serial_data(serial, NULL);
+ }
+ 
+ 
+@@ -2916,7 +2926,8 @@ static struct usb_serial_driver edgeport_1port_device = {
+ 	.throttle		= edge_throttle,
+ 	.unthrottle		= edge_unthrottle,
+ 	.attach			= edge_startup,
+-	.shutdown		= edge_shutdown,
++	.disconnect		= edge_disconnect,
++	.release		= edge_release,
+ 	.port_probe		= edge_create_sysfs_attrs,
+ 	.ioctl			= edge_ioctl,
+ 	.set_termios		= edge_set_termios,
+@@ -2945,7 +2956,8 @@ static struct usb_serial_driver edgeport_2port_device = {
+ 	.throttle		= edge_throttle,
+ 	.unthrottle		= edge_unthrottle,
+ 	.attach			= edge_startup,
+-	.shutdown		= edge_shutdown,
++	.disconnect		= edge_disconnect,
++	.release		= edge_release,
+ 	.port_probe		= edge_create_sysfs_attrs,
+ 	.ioctl			= edge_ioctl,
+ 	.set_termios		= edge_set_termios,
+diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
+index cd62825..b70b0a0 100644
+--- a/drivers/usb/serial/ipaq.c
++++ b/drivers/usb/serial/ipaq.c
+@@ -80,7 +80,6 @@ static void ipaq_close(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static int  ipaq_calc_num_ports(struct usb_serial *serial);
+ static int  ipaq_startup(struct usb_serial *serial);
+-static void ipaq_shutdown(struct usb_serial *serial);
+ static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
+ 			const unsigned char *buf, int count);
+ static int ipaq_write_bulk(struct usb_serial_port *port,
+@@ -577,7 +576,6 @@ static struct usb_serial_driver ipaq_device = {
+ 	.close =		ipaq_close,
+ 	.attach =		ipaq_startup,
+ 	.calc_num_ports =	ipaq_calc_num_ports,
+-	.shutdown =		ipaq_shutdown,
+ 	.write =		ipaq_write,
+ 	.write_room =		ipaq_write_room,
+ 	.chars_in_buffer =	ipaq_chars_in_buffer,
+@@ -992,11 +990,6 @@ static int ipaq_startup(struct usb_serial *serial)
+ 	return usb_reset_configuration(serial->dev);
+ }
+ 
+-static void ipaq_shutdown(struct usb_serial *serial)
+-{
+-	dbg("%s", __func__);
+-}
+-
+ static int __init ipaq_init(void)
+ {
+ 	int retval;
+diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
+index 4473d44..c03015b 100644
+--- a/drivers/usb/serial/iuu_phoenix.c
++++ b/drivers/usb/serial/iuu_phoenix.c
+@@ -122,8 +122,8 @@ static int iuu_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-/* Shutdown function */
+-static void iuu_shutdown(struct usb_serial *serial)
++/* Release function */
++static void iuu_release(struct usb_serial *serial)
+ {
+ 	struct usb_serial_port *port = serial->port[0];
+ 	struct iuu_private *priv = usb_get_serial_port_data(port);
+@@ -1176,7 +1176,7 @@ static struct usb_serial_driver iuu_device = {
+ 	.tiocmget = iuu_tiocmget,
+ 	.tiocmset = iuu_tiocmset,
+ 	.attach = iuu_startup,
+-	.shutdown = iuu_shutdown,
++	.release = iuu_release,
+ };
+ 
+ static int __init iuu_init(void)
+diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
+index 00daa8f..8c69c3c 100644
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -2682,7 +2682,7 @@ static int keyspan_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void keyspan_shutdown(struct usb_serial *serial)
++static void keyspan_disconnect(struct usb_serial *serial)
+ {
+ 	int				i, j;
+ 	struct usb_serial_port		*port;
+@@ -2722,6 +2722,17 @@ static void keyspan_shutdown(struct usb_serial *serial)
+ 			usb_free_urb(p_priv->out_urbs[j]);
+ 		}
+ 	}
++}
++
++static void keyspan_release(struct usb_serial *serial)
++{
++	int				i;
++	struct usb_serial_port		*port;
++	struct keyspan_serial_private 	*s_priv;
++
++	dbg("%s", __func__);
++
++	s_priv = usb_get_serial_data(serial);
+ 
+ 	/*  dbg("Freeing serial->private."); */
+ 	kfree(s_priv);
+diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
+index 38b4582..4961c26 100644
+--- a/drivers/usb/serial/keyspan.h
++++ b/drivers/usb/serial/keyspan.h
+@@ -42,7 +42,8 @@ static void keyspan_close		(struct tty_struct *tty,
+ 					 struct usb_serial_port *port,
+ 					 struct file *filp);
+ static int  keyspan_startup		(struct usb_serial *serial);
+-static void keyspan_shutdown		(struct usb_serial *serial);
++static void keyspan_disconnect		(struct usb_serial *serial);
++static void keyspan_release		(struct usb_serial *serial);
+ static int  keyspan_write_room		(struct tty_struct *tty);
+ 
+ static int  keyspan_write		(struct tty_struct *tty,
+@@ -569,7 +570,8 @@ static struct usb_serial_driver keyspan_1port_device = {
+ 	.tiocmget		= keyspan_tiocmget,
+ 	.tiocmset		= keyspan_tiocmset,
+ 	.attach			= keyspan_startup,
+-	.shutdown		= keyspan_shutdown,
++	.disconnect		= keyspan_disconnect,
++	.release		= keyspan_release,
+ };
+ 
+ static struct usb_serial_driver keyspan_2port_device = {
+@@ -589,7 +591,8 @@ static struct usb_serial_driver keyspan_2port_device = {
+ 	.tiocmget		= keyspan_tiocmget,
+ 	.tiocmset		= keyspan_tiocmset,
+ 	.attach			= keyspan_startup,
+-	.shutdown		= keyspan_shutdown,
++	.disconnect		= keyspan_disconnect,
++	.release		= keyspan_release,
+ };
+ 
+ static struct usb_serial_driver keyspan_4port_device = {
+@@ -609,7 +612,8 @@ static struct usb_serial_driver keyspan_4port_device = {
+ 	.tiocmget		= keyspan_tiocmget,
+ 	.tiocmset		= keyspan_tiocmset,
+ 	.attach			= keyspan_startup,
+-	.shutdown		= keyspan_shutdown,
++	.disconnect		= keyspan_disconnect,
++	.release		= keyspan_release,
+ };
+ 
+ #endif
+diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
+index bf1ae24..d2e2b91 100644
+--- a/drivers/usb/serial/keyspan_pda.c
++++ b/drivers/usb/serial/keyspan_pda.c
+@@ -795,7 +795,7 @@ static int keyspan_pda_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void keyspan_pda_shutdown(struct usb_serial *serial)
++static void keyspan_pda_release(struct usb_serial *serial)
+ {
+ 	dbg("%s", __func__);
+ 
+@@ -853,7 +853,7 @@ static struct usb_serial_driver keyspan_pda_device = {
+ 	.tiocmget =		keyspan_pda_tiocmget,
+ 	.tiocmset =		keyspan_pda_tiocmset,
+ 	.attach =		keyspan_pda_startup,
+-	.shutdown =		keyspan_pda_shutdown,
++	.release =		keyspan_pda_release,
+ };
+ 
+ 
+diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
+index fcd9082..272a94f 100644
+--- a/drivers/usb/serial/kl5kusb105.c
++++ b/drivers/usb/serial/kl5kusb105.c
+@@ -73,7 +73,8 @@ static int debug;
+  * Function prototypes
+  */
+ static int  klsi_105_startup(struct usb_serial *serial);
+-static void klsi_105_shutdown(struct usb_serial *serial);
++static void klsi_105_disconnect(struct usb_serial *serial);
++static void klsi_105_release(struct usb_serial *serial);
+ static int  klsi_105_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static void klsi_105_close(struct tty_struct *tty,
+@@ -132,7 +133,8 @@ static struct usb_serial_driver kl5kusb105d_device = {
+ 	.tiocmget =          klsi_105_tiocmget,
+ 	.tiocmset =          klsi_105_tiocmset,
+ 	.attach =	     klsi_105_startup,
+-	.shutdown =	     klsi_105_shutdown,
++	.disconnect =	     klsi_105_disconnect,
++	.release =	     klsi_105_release,
+ 	.throttle =	     klsi_105_throttle,
+ 	.unthrottle =	     klsi_105_unthrottle,
+ };
+@@ -316,7 +318,7 @@ err_cleanup:
+ } /* klsi_105_startup */
+ 
+ 
+-static void klsi_105_shutdown(struct usb_serial *serial)
++static void klsi_105_disconnect(struct usb_serial *serial)
+ {
+ 	int i;
+ 
+@@ -326,33 +328,36 @@ static void klsi_105_shutdown(struct usb_serial *serial)
+ 	for (i = 0; i < serial->num_ports; ++i) {
+ 		struct klsi_105_private *priv =
+ 				usb_get_serial_port_data(serial->port[i]);
+-		unsigned long flags;
+ 
+ 		if (priv) {
+ 			/* kill our write urb pool */
+ 			int j;
+ 			struct urb **write_urbs = priv->write_urb_pool;
+-			spin_lock_irqsave(&priv->lock, flags);
+ 
+ 			for (j = 0; j < NUM_URBS; j++) {
+ 				if (write_urbs[j]) {
+-					/* FIXME - uncomment the following
+-					 * usb_kill_urb call when the host
+-					 * controllers get fixed to set
+-					 * urb->dev = NULL after the urb is
+-					 * finished.  Otherwise this call
+-					 * oopses. */
+-					/* usb_kill_urb(write_urbs[j]); */
+-					kfree(write_urbs[j]->transfer_buffer);
++					usb_kill_urb(write_urbs[j]);
+ 					usb_free_urb(write_urbs[j]);
+ 				}
+ 			}
+-			spin_unlock_irqrestore(&priv->lock, flags);
+-			kfree(priv);
+-			usb_set_serial_port_data(serial->port[i], NULL);
+ 		}
+ 	}
+-} /* klsi_105_shutdown */
++} /* klsi_105_disconnect */
++
++
++static void klsi_105_release(struct usb_serial *serial)
++{
++	int i;
++
++	dbg("%s", __func__);
++
++	for (i = 0; i < serial->num_ports; ++i) {
++		struct klsi_105_private *priv =
++				usb_get_serial_port_data(serial->port[i]);
++
++		kfree(priv);
++	}
++} /* klsi_105_release */
+ 
+ static int  klsi_105_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp)
+diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
+index c148544..d88368c 100644
+--- a/drivers/usb/serial/kobil_sct.c
++++ b/drivers/usb/serial/kobil_sct.c
+@@ -69,7 +69,7 @@ static int debug;
+ 
+ /* Function prototypes */
+ static int  kobil_startup(struct usb_serial *serial);
+-static void kobil_shutdown(struct usb_serial *serial);
++static void kobil_release(struct usb_serial *serial);
+ static int  kobil_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static void kobil_close(struct tty_struct *tty, struct usb_serial_port *port,
+@@ -118,7 +118,7 @@ static struct usb_serial_driver kobil_device = {
+ 	.id_table =		id_table,
+ 	.num_ports =		1,
+ 	.attach =		kobil_startup,
+-	.shutdown =		kobil_shutdown,
++	.release =		kobil_release,
+ 	.ioctl =		kobil_ioctl,
+ 	.set_termios =		kobil_set_termios,
+ 	.tiocmget =		kobil_tiocmget,
+@@ -202,17 +202,13 @@ static int kobil_startup(struct usb_serial *serial)
+ }
+ 
+ 
+-static void kobil_shutdown(struct usb_serial *serial)
++static void kobil_release(struct usb_serial *serial)
+ {
+ 	int i;
+ 	dbg("%s - port %d", __func__, serial->port[0]->number);
+ 
+-	for (i = 0; i < serial->num_ports; ++i) {
+-		while (serial->port[i]->port.count > 0)
+-			kobil_close(NULL, serial->port[i], NULL);
++	for (i = 0; i < serial->num_ports; ++i)
+ 		kfree(usb_get_serial_port_data(serial->port[i]));
+-		usb_set_serial_port_data(serial->port[i], NULL);
+-	}
+ }
+ 
+ 
+diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
+index 82930a7..08ba8e6 100644
+--- a/drivers/usb/serial/mct_u232.c
++++ b/drivers/usb/serial/mct_u232.c
+@@ -92,7 +92,7 @@ static int debug;
+  * Function prototypes
+  */
+ static int  mct_u232_startup(struct usb_serial *serial);
+-static void mct_u232_shutdown(struct usb_serial *serial);
++static void mct_u232_release(struct usb_serial *serial);
+ static int  mct_u232_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static void mct_u232_close(struct tty_struct *tty,
+@@ -148,7 +148,7 @@ static struct usb_serial_driver mct_u232_device = {
+ 	.tiocmget =	     mct_u232_tiocmget,
+ 	.tiocmset =	     mct_u232_tiocmset,
+ 	.attach =	     mct_u232_startup,
+-	.shutdown =	     mct_u232_shutdown,
++	.release =	     mct_u232_release,
+ };
+ 
+ 
+@@ -406,7 +406,7 @@ static int mct_u232_startup(struct usb_serial *serial)
+ } /* mct_u232_startup */
+ 
+ 
+-static void mct_u232_shutdown(struct usb_serial *serial)
++static void mct_u232_release(struct usb_serial *serial)
+ {
+ 	struct mct_u232_private *priv;
+ 	int i;
+@@ -416,12 +416,9 @@ static void mct_u232_shutdown(struct usb_serial *serial)
+ 	for (i = 0; i < serial->num_ports; ++i) {
+ 		/* My special items, the standard routines free my urbs */
+ 		priv = usb_get_serial_port_data(serial->port[i]);
+-		if (priv) {
+-			usb_set_serial_port_data(serial->port[i], NULL);
+-			kfree(priv);
+-		}
++		kfree(priv);
+ 	}
+-} /* mct_u232_shutdown */
++} /* mct_u232_release */
+ 
+ static int  mct_u232_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp)
+diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
+index 24e3b5d..e0137ec 100644
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -1522,19 +1522,16 @@ static int mos7720_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void mos7720_shutdown(struct usb_serial *serial)
++static void mos7720_release(struct usb_serial *serial)
+ {
+ 	int i;
+ 
+ 	/* free private structure allocated for serial port */
+-	for (i = 0; i < serial->num_ports; ++i) {
++	for (i = 0; i < serial->num_ports; ++i)
+ 		kfree(usb_get_serial_port_data(serial->port[i]));
+-		usb_set_serial_port_data(serial->port[i], NULL);
+-	}
+ 
+ 	/* free private structure allocated for serial device */
+ 	kfree(usb_get_serial_data(serial));
+-	usb_set_serial_data(serial, NULL);
+ }
+ 
+ static struct usb_driver usb_driver = {
+@@ -1559,7 +1556,7 @@ static struct usb_serial_driver moschip7720_2port_driver = {
+ 	.throttle		= mos7720_throttle,
+ 	.unthrottle		= mos7720_unthrottle,
+ 	.attach			= mos7720_startup,
+-	.shutdown		= mos7720_shutdown,
++	.release		= mos7720_release,
+ 	.ioctl			= mos7720_ioctl,
+ 	.set_termios		= mos7720_set_termios,
+ 	.write			= mos7720_write,
+diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
+index 84fb1dc..3d30268 100644
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -2673,16 +2673,16 @@ error:
+ }
+ 
+ /****************************************************************************
+- * mos7840_shutdown
++ * mos7840_disconnect
+  *	This function is called whenever the device is removed from the usb bus.
+  ****************************************************************************/
+ 
+-static void mos7840_shutdown(struct usb_serial *serial)
++static void mos7840_disconnect(struct usb_serial *serial)
+ {
+ 	int i;
+ 	unsigned long flags;
+ 	struct moschip_port *mos7840_port;
+-	dbg("%s \n", " shutdown :entering..........");
++	dbg("%s \n", " disconnect :entering..........");
+ 
+ 	if (!serial) {
+ 		dbg("%s", "Invalid Handler \n");
+@@ -2702,11 +2702,42 @@ static void mos7840_shutdown(struct usb_serial *serial)
+ 			mos7840_port->zombie = 1;
+ 			spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
+ 			usb_kill_urb(mos7840_port->control_urb);
++		}
++	}
++
++	dbg("%s", "Thank u :: ");
++
++}
++
++/****************************************************************************
++ * mos7840_release
++ *	This function is called when the usb_serial structure is freed.
++ ****************************************************************************/
++
++static void mos7840_release(struct usb_serial *serial)
++{
++	int i;
++	struct moschip_port *mos7840_port;
++	dbg("%s", " release :entering..........");
++
++	if (!serial) {
++		dbg("%s", "Invalid Handler");
++		return;
++	}
++
++	/* check for the ports to be closed,close the ports and disconnect */
++
++	/* free private structure allocated for serial port  *
++	 * stop reads and writes on all ports                */
++
++	for (i = 0; i < serial->num_ports; ++i) {
++		mos7840_port = mos7840_get_port_private(serial->port[i]);
++		dbg("mos7840_port %d = %p", i, mos7840_port);
++		if (mos7840_port) {
+ 			kfree(mos7840_port->ctrl_buf);
+ 			kfree(mos7840_port->dr);
+ 			kfree(mos7840_port);
+ 		}
+-		mos7840_set_port_private(serial->port[i], NULL);
+ 	}
+ 
+ 	dbg("%s\n", "Thank u :: ");
+@@ -2747,7 +2778,8 @@ static struct usb_serial_driver moschip7840_4port_device = {
+ 	.tiocmget = mos7840_tiocmget,
+ 	.tiocmset = mos7840_tiocmset,
+ 	.attach = mos7840_startup,
+-	.shutdown = mos7840_shutdown,
++	.disconnect = mos7840_disconnect,
++	.release = mos7840_release,
+ 	.read_bulk_callback = mos7840_bulk_in_callback,
+ 	.read_int_callback = mos7840_interrupt_callback,
+ };
+diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
+index df65397..65fb5c6 100644
+--- a/drivers/usb/serial/omninet.c
++++ b/drivers/usb/serial/omninet.c
+@@ -73,7 +73,8 @@ static void omninet_write_bulk_callback(struct urb *urb);
+ static int  omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
+ 				const unsigned char *buf, int count);
+ static int  omninet_write_room(struct tty_struct *tty);
+-static void omninet_shutdown(struct usb_serial *serial);
++static void omninet_disconnect(struct usb_serial *serial);
++static void omninet_release(struct usb_serial *serial);
+ static int omninet_attach(struct usb_serial *serial);
+ 
+ static struct usb_device_id id_table[] = {
+@@ -109,7 +110,8 @@ static struct usb_serial_driver zyxel_omninet_device = {
+ 	.write_room =		omninet_write_room,
+ 	.read_bulk_callback =	omninet_read_bulk_callback,
+ 	.write_bulk_callback =	omninet_write_bulk_callback,
+-	.shutdown =		omninet_shutdown,
++	.disconnect =		omninet_disconnect,
++	.release =		omninet_release,
+ };
+ 
+ 
+@@ -347,13 +349,22 @@ static void omninet_write_bulk_callback(struct urb *urb)
+ }
+ 
+ 
+-static void omninet_shutdown(struct usb_serial *serial)
++static void omninet_disconnect(struct usb_serial *serial)
+ {
+ 	struct usb_serial_port *wport = serial->port[1];
+-	struct usb_serial_port *port = serial->port[0];
++
+ 	dbg("%s", __func__);
+ 
+ 	usb_kill_urb(wport->write_urb);
++}
++
++
++static void omninet_release(struct usb_serial *serial)
++{
++	struct usb_serial_port *port = serial->port[0];
++
++	dbg("%s", __func__);
++
+ 	kfree(usb_get_serial_port_data(port));
+ }
+ 
+diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
+index b500ad1..1e99ae0 100644
+--- a/drivers/usb/serial/opticon.c
++++ b/drivers/usb/serial/opticon.c
+@@ -464,7 +464,7 @@ error:
+ 	return retval;
+ }
+ 
+-static void opticon_shutdown(struct usb_serial *serial)
++static void opticon_disconnect(struct usb_serial *serial)
+ {
+ 	struct opticon_private *priv = usb_get_serial_data(serial);
+ 
+@@ -472,9 +472,16 @@ static void opticon_shutdown(struct usb_serial *serial)
+ 
+ 	usb_kill_urb(priv->bulk_read_urb);
+ 	usb_free_urb(priv->bulk_read_urb);
++}
++
++static void opticon_release(struct usb_serial *serial)
++{
++	struct opticon_private *priv = usb_get_serial_data(serial);
++
++	dbg("%s", __func__);
++
+ 	kfree(priv->bulk_in_buffer);
+ 	kfree(priv);
+-	usb_set_serial_data(serial, NULL);
+ }
+ 
+ static int opticon_suspend(struct usb_interface *intf, pm_message_t message)
+@@ -525,7 +532,8 @@ static struct usb_serial_driver opticon_device = {
+ 	.close =		opticon_close,
+ 	.write =		opticon_write,
+ 	.write_room = 		opticon_write_room,
+-	.shutdown =		opticon_shutdown,
++	.disconnect =		opticon_disconnect,
++	.release =		opticon_release,
+ 	.throttle = 		opticon_throttle,
+ 	.unthrottle =		opticon_unthrottle,
+ 	.ioctl =		opticon_ioctl,
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 7817b82..ab3d883 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -48,7 +48,8 @@ static int  option_open(struct tty_struct *tty, struct usb_serial_port *port,
+ static void option_close(struct tty_struct *tty, struct usb_serial_port *port,
+ 							struct file *filp);
+ static int  option_startup(struct usb_serial *serial);
+-static void option_shutdown(struct usb_serial *serial);
++static void option_disconnect(struct usb_serial *serial);
++static void option_release(struct usb_serial *serial);
+ static int  option_write_room(struct tty_struct *tty);
+ 
+ static void option_instat_callback(struct urb *urb);
+@@ -558,7 +559,8 @@ static struct usb_serial_driver option_1port_device = {
+ 	.tiocmget          = option_tiocmget,
+ 	.tiocmset          = option_tiocmset,
+ 	.attach            = option_startup,
+-	.shutdown          = option_shutdown,
++	.disconnect        = option_disconnect,
++	.release           = option_release,
+ 	.read_int_callback = option_instat_callback,
+ 	.suspend           = option_suspend,
+ 	.resume            = option_resume,
+@@ -1129,7 +1131,14 @@ static void stop_read_write_urbs(struct usb_serial *serial)
+ 	}
+ }
+ 
+-static void option_shutdown(struct usb_serial *serial)
++static void option_disconnect(struct usb_serial *serial)
++{
++	dbg("%s", __func__);
++
++	stop_read_write_urbs(serial);
++}
++
++static void option_release(struct usb_serial *serial)
+ {
+ 	int i, j;
+ 	struct usb_serial_port *port;
+@@ -1137,8 +1146,6 @@ static void option_shutdown(struct usb_serial *serial)
+ 
+ 	dbg("%s", __func__);
+ 
+-	stop_read_write_urbs(serial);
+-
+ 	/* Now free them */
+ 	for (i = 0; i < serial->num_ports; ++i) {
+ 		port = serial->port[i];
+diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
+index ba551f0..f7388ef 100644
+--- a/drivers/usb/serial/oti6858.c
++++ b/drivers/usb/serial/oti6858.c
+@@ -160,7 +160,7 @@ static int oti6858_tiocmget(struct tty_struct *tty, struct file *file);
+ static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
+ 				unsigned int set, unsigned int clear);
+ static int oti6858_startup(struct usb_serial *serial);
+-static void oti6858_shutdown(struct usb_serial *serial);
++static void oti6858_release(struct usb_serial *serial);
+ 
+ /* functions operating on buffers */
+ static struct oti6858_buf *oti6858_buf_alloc(unsigned int size);
+@@ -195,7 +195,7 @@ static struct usb_serial_driver oti6858_device = {
+ 	.write_room =		oti6858_write_room,
+ 	.chars_in_buffer =	oti6858_chars_in_buffer,
+ 	.attach =		oti6858_startup,
+-	.shutdown =		oti6858_shutdown,
++	.release =		oti6858_release,
+ };
+ 
+ struct oti6858_private {
+@@ -829,7 +829,7 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
+ }
+ 
+ 
+-static void oti6858_shutdown(struct usb_serial *serial)
++static void oti6858_release(struct usb_serial *serial)
+ {
+ 	struct oti6858_private *priv;
+ 	int i;
+@@ -841,7 +841,6 @@ static void oti6858_shutdown(struct usb_serial *serial)
+ 		if (priv) {
+ 			oti6858_buf_free(priv->buf);
+ 			kfree(priv);
+-			usb_set_serial_port_data(serial->port[i], NULL);
+ 		}
+ 	}
+ }
+diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
+index 751a533..4cf1ed1 100644
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -897,7 +897,7 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
+ 		dbg("%s - error sending break = %d", __func__, result);
+ }
+ 
+-static void pl2303_shutdown(struct usb_serial *serial)
++static void pl2303_release(struct usb_serial *serial)
+ {
+ 	int i;
+ 	struct pl2303_private *priv;
+@@ -909,7 +909,6 @@ static void pl2303_shutdown(struct usb_serial *serial)
+ 		if (priv) {
+ 			pl2303_buf_free(priv->buf);
+ 			kfree(priv);
+-			usb_set_serial_port_data(serial->port[i], NULL);
+ 		}
+ 	}
+ }
+@@ -1137,7 +1136,7 @@ static struct usb_serial_driver pl2303_device = {
+ 	.write_room =		pl2303_write_room,
+ 	.chars_in_buffer =	pl2303_chars_in_buffer,
+ 	.attach =		pl2303_startup,
+-	.shutdown =		pl2303_shutdown,
++	.release =		pl2303_release,
+ };
+ 
+ static int __init pl2303_init(void)
+diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
+index 913225c..5a26ed8 100644
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -699,7 +699,7 @@ static int sierra_startup(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
+-static void sierra_shutdown(struct usb_serial *serial)
++static void sierra_disconnect(struct usb_serial *serial)
+ {
+ 	int i, j;
+ 	struct usb_serial_port *port;
+@@ -718,10 +718,29 @@ static void sierra_shutdown(struct usb_serial *serial)
+ 		for (j = 0; j < N_IN_URB; j++) {
+ 			usb_kill_urb(portdata->in_urbs[j]);
+ 			usb_free_urb(portdata->in_urbs[j]);
+-			kfree(portdata->in_buffer[j]);
+ 		}
++	}
++}
++
++static void sierra_release(struct usb_serial *serial)
++{
++	int i, j;
++	struct usb_serial_port *port;
++	struct sierra_port_private *portdata;
++
++	dev_dbg(&serial->dev->dev, "%s\n", __func__);
++
++	for (i = 0; i < serial->num_ports; ++i) {
++		port = serial->port[i];
++		if (!port)
++			continue;
++		portdata = usb_get_serial_port_data(port);
++		if (!portdata)
++			continue;
++
++		for (j = 0; j < N_IN_URB; j++)
++			kfree(portdata->in_buffer[j]);
+ 		kfree(portdata);
+-		usb_set_serial_port_data(port, NULL);
+ 	}
+ }
+ 
+@@ -743,7 +762,8 @@ static struct usb_serial_driver sierra_device = {
+ 	.tiocmget          = sierra_tiocmget,
+ 	.tiocmset          = sierra_tiocmset,
+ 	.attach            = sierra_startup,
+-	.shutdown          = sierra_shutdown,
++	.disconnect        = sierra_disconnect,
++	.release           = sierra_release,
+ 	.read_int_callback = sierra_instat_callback,
+ };
+ 
+diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
+index 5e7528c..f5403b0 100644
+--- a/drivers/usb/serial/spcp8x5.c
++++ b/drivers/usb/serial/spcp8x5.c
+@@ -356,7 +356,7 @@ cleanup:
+ }
+ 
+ /* call when the device plug out. free all the memory alloced by probe */
+-static void spcp8x5_shutdown(struct usb_serial *serial)
++static void spcp8x5_release(struct usb_serial *serial)
+ {
+ 	int i;
+ 	struct spcp8x5_private *priv;
+@@ -366,7 +366,6 @@ static void spcp8x5_shutdown(struct usb_serial *serial)
+ 		if (priv) {
+ 			free_ringbuf(priv->buf);
+ 			kfree(priv);
+-			usb_set_serial_port_data(serial->port[i] , NULL);
+ 		}
+ 	}
+ }
+@@ -1043,7 +1042,7 @@ static struct usb_serial_driver spcp8x5_device = {
+ 	.write_bulk_callback	= spcp8x5_write_bulk_callback,
+ 	.chars_in_buffer 	= spcp8x5_chars_in_buffer,
+ 	.attach 		= spcp8x5_startup,
+-	.shutdown 		= spcp8x5_shutdown,
++	.release 		= spcp8x5_release,
+ };
+ 
+ static int __init spcp8x5_init(void)
+diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
+index 69879e4..b7a6bc8 100644
+--- a/drivers/usb/serial/symbolserial.c
++++ b/drivers/usb/serial/symbolserial.c
+@@ -268,7 +268,7 @@ error:
+ 	return retval;
+ }
+ 
+-static void symbol_shutdown(struct usb_serial *serial)
++static void symbol_disconnect(struct usb_serial *serial)
+ {
+ 	struct symbol_private *priv = usb_get_serial_data(serial);
+ 
+@@ -276,9 +276,16 @@ static void symbol_shutdown(struct usb_serial *serial)
+ 
+ 	usb_kill_urb(priv->int_urb);
+ 	usb_free_urb(priv->int_urb);
++}
++
++static void symbol_release(struct usb_serial *serial)
++{
++	struct symbol_private *priv = usb_get_serial_data(serial);
++
++	dbg("%s", __func__);
++
+ 	kfree(priv->int_buffer);
+ 	kfree(priv);
+-	usb_set_serial_data(serial, NULL);
+ }
+ 
+ static struct usb_driver symbol_driver = {
+@@ -300,7 +307,8 @@ static struct usb_serial_driver symbol_device = {
+ 	.attach =		symbol_startup,
+ 	.open =			symbol_open,
+ 	.close =		symbol_close,
+-	.shutdown =		symbol_shutdown,
++	.disconnect =		symbol_disconnect,
++	.release =		symbol_release,
+ 	.throttle = 		symbol_throttle,
+ 	.unthrottle =		symbol_unthrottle,
+ };
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
+index 0a64bac..ef5f756 100644
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -97,7 +97,7 @@ struct ti_device {
+ /* Function Declarations */
+ 
+ static int ti_startup(struct usb_serial *serial);
+-static void ti_shutdown(struct usb_serial *serial);
++static void ti_release(struct usb_serial *serial);
+ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
+ 		struct file *file);
+ static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
+@@ -231,7 +231,7 @@ static struct usb_serial_driver ti_1port_device = {
+ 	.id_table		= ti_id_table_3410,
+ 	.num_ports		= 1,
+ 	.attach			= ti_startup,
+-	.shutdown		= ti_shutdown,
++	.release		= ti_release,
+ 	.open			= ti_open,
+ 	.close			= ti_close,
+ 	.write			= ti_write,
+@@ -259,7 +259,7 @@ static struct usb_serial_driver ti_2port_device = {
+ 	.id_table		= ti_id_table_5052,
+ 	.num_ports		= 2,
+ 	.attach			= ti_startup,
+-	.shutdown		= ti_shutdown,
++	.release		= ti_release,
+ 	.open			= ti_open,
+ 	.close			= ti_close,
+ 	.write			= ti_write,
+@@ -474,7 +474,7 @@ free_tdev:
+ }
+ 
+ 
+-static void ti_shutdown(struct usb_serial *serial)
++static void ti_release(struct usb_serial *serial)
+ {
+ 	int i;
+ 	struct ti_device *tdev = usb_get_serial_data(serial);
+@@ -487,12 +487,10 @@ static void ti_shutdown(struct usb_serial *serial)
+ 		if (tport) {
+ 			ti_buf_free(tport->tp_write_buf);
+ 			kfree(tport);
+-			usb_set_serial_port_data(serial->port[i], NULL);
+ 		}
+ 	}
+ 
+ 	kfree(tdev);
+-	usb_set_serial_data(serial, NULL);
+ }
+ 
+ 
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+index f331e2b..131fc74 100644
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -141,6 +141,14 @@ static void destroy_serial(struct kref *kref)
+ 	if (serial->minor != SERIAL_TTY_NO_MINOR)
+ 		return_serial(serial);
+ 
++	serial->type->release(serial);
++
++	for (i = 0; i < serial->num_ports; ++i) {
++		port = serial->port[i];
++		if (port)
++			put_device(&port->dev);
++	}
++
+ 	/* If this is a "fake" port, we have to clean it up here, as it will
+ 	 * not get cleaned up in port_release() as it was never registered with
+ 	 * the driver core */
+@@ -148,9 +156,8 @@ static void destroy_serial(struct kref *kref)
+ 		for (i = serial->num_ports;
+ 					i < serial->num_port_pointers; ++i) {
+ 			port = serial->port[i];
+-			if (!port)
+-				continue;
+-			port_free(port);
++			if (port)
++				port_free(port);
+ 		}
+ 	}
+ 
+@@ -1062,10 +1069,6 @@ void usb_serial_disconnect(struct usb_interface *interface)
+ 	serial->disconnected = 1;
+ 	mutex_unlock(&serial->disc_mutex);
+ 
+-	/* Unfortunately, many of the sub-drivers expect the port structures
+-	 * to exist when their shutdown method is called, so we have to go
+-	 * through this awkward two-step unregistration procedure.
+-	 */
+ 	for (i = 0; i < serial->num_ports; ++i) {
+ 		port = serial->port[i];
+ 		if (port) {
+@@ -1079,14 +1082,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
+ 			device_del(&port->dev);
+ 		}
+ 	}
+-	serial->type->shutdown(serial);
+-	for (i = 0; i < serial->num_ports; ++i) {
+-		port = serial->port[i];
+-		if (port) {
+-			put_device(&port->dev);
+-			serial->port[i] = NULL;
+-		}
+-	}
++	serial->type->disconnect(serial);
+ 
+ 	/* let the last holder of this object
+ 	 * cause it to be cleaned up */
+@@ -1262,7 +1258,8 @@ static void fixup_generic(struct usb_serial_driver *device)
+ 	set_to_generic_if_null(device, chars_in_buffer);
+ 	set_to_generic_if_null(device, read_bulk_callback);
+ 	set_to_generic_if_null(device, write_bulk_callback);
+-	set_to_generic_if_null(device, shutdown);
++	set_to_generic_if_null(device, disconnect);
++	set_to_generic_if_null(device, release);
+ }
+ 
+ int usb_serial_register(struct usb_serial_driver *driver)
+diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
+index 5ac414b..e50f397 100644
+--- a/drivers/usb/serial/visor.c
++++ b/drivers/usb/serial/visor.c
+@@ -48,7 +48,7 @@ static void visor_unthrottle(struct tty_struct *tty);
+ static int  visor_probe(struct usb_serial *serial,
+ 					const struct usb_device_id *id);
+ static int  visor_calc_num_ports(struct usb_serial *serial);
+-static void visor_shutdown(struct usb_serial *serial);
++static void visor_release(struct usb_serial *serial);
+ static void visor_write_bulk_callback(struct urb *urb);
+ static void visor_read_bulk_callback(struct urb *urb);
+ static void visor_read_int_callback(struct urb *urb);
+@@ -203,7 +203,7 @@ static struct usb_serial_driver handspring_device = {
+ 	.attach =		treo_attach,
+ 	.probe =		visor_probe,
+ 	.calc_num_ports =	visor_calc_num_ports,
+-	.shutdown =		visor_shutdown,
++	.release =		visor_release,
+ 	.write =		visor_write,
+ 	.write_room =		visor_write_room,
+ 	.write_bulk_callback =	visor_write_bulk_callback,
+@@ -228,7 +228,7 @@ static struct usb_serial_driver clie_5_device = {
+ 	.attach =		clie_5_attach,
+ 	.probe =		visor_probe,
+ 	.calc_num_ports =	visor_calc_num_ports,
+-	.shutdown =		visor_shutdown,
++	.release =		visor_release,
+ 	.write =		visor_write,
+ 	.write_room =		visor_write_room,
+ 	.write_bulk_callback =	visor_write_bulk_callback,
+@@ -920,7 +920,7 @@ static int clie_5_attach(struct usb_serial *serial)
+ 	return generic_startup(serial);
+ }
+ 
+-static void visor_shutdown(struct usb_serial *serial)
++static void visor_release(struct usb_serial *serial)
+ {
+ 	struct visor_private *priv;
+ 	int i;
+@@ -929,10 +929,7 @@ static void visor_shutdown(struct usb_serial *serial)
+ 
+ 	for (i = 0; i < serial->num_ports; i++) {
+ 		priv = usb_get_serial_port_data(serial->port[i]);
+-		if (priv) {
+-			usb_set_serial_port_data(serial->port[i], NULL);
+-			kfree(priv);
+-		}
++		kfree(priv);
+ 	}
+ }
+ 
+diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
+index 5335d32..319ec07 100644
+--- a/drivers/usb/serial/whiteheat.c
++++ b/drivers/usb/serial/whiteheat.c
+@@ -144,7 +144,7 @@ static int  whiteheat_firmware_attach(struct usb_serial *serial);
+ 
+ /* function prototypes for the Connect Tech WhiteHEAT serial converter */
+ static int  whiteheat_attach(struct usb_serial *serial);
+-static void whiteheat_shutdown(struct usb_serial *serial);
++static void whiteheat_release(struct usb_serial *serial);
+ static int  whiteheat_open(struct tty_struct *tty,
+ 			struct usb_serial_port *port, struct file *filp);
+ static void whiteheat_close(struct tty_struct *tty,
+@@ -190,7 +190,7 @@ static struct usb_serial_driver whiteheat_device = {
+ 	.id_table =		id_table_std,
+ 	.num_ports =		4,
+ 	.attach =		whiteheat_attach,
+-	.shutdown =		whiteheat_shutdown,
++	.release =		whiteheat_release,
+ 	.open =			whiteheat_open,
+ 	.close =		whiteheat_close,
+ 	.write =		whiteheat_write,
+@@ -618,7 +618,7 @@ no_command_buffer:
+ }
+ 
+ 
+-static void whiteheat_shutdown(struct usb_serial *serial)
++static void whiteheat_release(struct usb_serial *serial)
+ {
+ 	struct usb_serial_port *command_port;
+ 	struct usb_serial_port *port;
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 9f7270f..ab3ccc1 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -39,6 +39,13 @@ config FS_POSIX_ACL
+ 	bool
+ 	default n
+ 
++source "fs/xfs/Kconfig"
++source "fs/gfs2/Kconfig"
++source "fs/ocfs2/Kconfig"
++source "fs/btrfs/Kconfig"
++
++endif # BLOCK
++
+ config FILE_LOCKING
+ 	bool "Enable POSIX file locking API" if EMBEDDED
+ 	default y
+@@ -47,13 +54,6 @@ config FILE_LOCKING
+           for filesystems like NFS and for the flock() system
+           call. Disabling this option saves about 11k.
+ 
+-source "fs/xfs/Kconfig"
+-source "fs/gfs2/Kconfig"
+-source "fs/ocfs2/Kconfig"
+-source "fs/btrfs/Kconfig"
+-
+-endif # BLOCK
+-
+ source "fs/notify/Kconfig"
+ 
+ source "fs/quota/Kconfig"
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 302ea15..bd44591 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -491,9 +491,9 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
+ 		return -EBADF;
+ 
+ 	xid = GetXid();
+-	mutex_unlock(&pCifsFile->fh_mutex);
++	mutex_lock(&pCifsFile->fh_mutex);
+ 	if (!pCifsFile->invalidHandle) {
+-		mutex_lock(&pCifsFile->fh_mutex);
++		mutex_unlock(&pCifsFile->fh_mutex);
+ 		FreeXid(xid);
+ 		return 0;
+ 	}
+@@ -524,7 +524,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
+ 	if (full_path == NULL) {
+ 		rc = -ENOMEM;
+ reopen_error_exit:
+-		mutex_lock(&pCifsFile->fh_mutex);
++		mutex_unlock(&pCifsFile->fh_mutex);
+ 		FreeXid(xid);
+ 		return rc;
+ 	}
+@@ -566,14 +566,14 @@ reopen_error_exit:
+ 			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+ 				CIFS_MOUNT_MAP_SPECIAL_CHR);
+ 	if (rc) {
+-		mutex_lock(&pCifsFile->fh_mutex);
++		mutex_unlock(&pCifsFile->fh_mutex);
+ 		cFYI(1, ("cifs_open returned 0x%x", rc));
+ 		cFYI(1, ("oplock: %d", oplock));
+ 	} else {
+ reopen_success:
+ 		pCifsFile->netfid = netfid;
+ 		pCifsFile->invalidHandle = false;
+-		mutex_lock(&pCifsFile->fh_mutex);
++		mutex_unlock(&pCifsFile->fh_mutex);
+ 		pCifsInode = CIFS_I(inode);
+ 		if (pCifsInode) {
+ 			if (can_flush) {
+diff --git a/fs/eventpoll.c b/fs/eventpoll.c
+index 5458e80..085c5c0 100644
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -98,7 +98,7 @@ struct epoll_filefd {
+ struct nested_call_node {
+ 	struct list_head llink;
+ 	void *cookie;
+-	int cpu;
++	void *ctx;
+ };
+ 
+ /*
+@@ -317,17 +317,17 @@ static void ep_nested_calls_init(struct nested_calls *ncalls)
+  * @nproc: Nested call core function pointer.
+  * @priv: Opaque data to be passed to the @nproc callback.
+  * @cookie: Cookie to be used to identify this nested call.
++ * @ctx: This instance context.
+  *
+  * Returns: Returns the code returned by the @nproc callback, or -1 if
+  *          the maximum recursion limit has been exceeded.
+  */
+ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
+ 			  int (*nproc)(void *, void *, int), void *priv,
+-			  void *cookie)
++			  void *cookie, void *ctx)
+ {
+ 	int error, call_nests = 0;
+ 	unsigned long flags;
+-	int this_cpu = get_cpu();
+ 	struct list_head *lsthead = &ncalls->tasks_call_list;
+ 	struct nested_call_node *tncur;
+ 	struct nested_call_node tnode;
+@@ -340,7 +340,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
+ 	 * very much limited.
+ 	 */
+ 	list_for_each_entry(tncur, lsthead, llink) {
+-		if (tncur->cpu == this_cpu &&
++		if (tncur->ctx == ctx &&
+ 		    (tncur->cookie == cookie || ++call_nests > max_nests)) {
+ 			/*
+ 			 * Ops ... loop detected or maximum nest level reached.
+@@ -352,7 +352,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
+ 	}
+ 
+ 	/* Add the current task and cookie to the list */
+-	tnode.cpu = this_cpu;
++	tnode.ctx = ctx;
+ 	tnode.cookie = cookie;
+ 	list_add(&tnode.llink, lsthead);
+ 
+@@ -364,10 +364,9 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
+ 	/* Remove the current task from the list */
+ 	spin_lock_irqsave(&ncalls->lock, flags);
+ 	list_del(&tnode.llink);
+- out_unlock:
++out_unlock:
+ 	spin_unlock_irqrestore(&ncalls->lock, flags);
+ 
+-	put_cpu();
+ 	return error;
+ }
+ 
+@@ -408,8 +407,12 @@ static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests)
+  */
+ static void ep_poll_safewake(wait_queue_head_t *wq)
+ {
++	int this_cpu = get_cpu();
++
+ 	ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS,
+-		       ep_poll_wakeup_proc, NULL, wq);
++		       ep_poll_wakeup_proc, NULL, wq, (void *) (long) this_cpu);
++
++	put_cpu();
+ }
+ 
+ /*
+@@ -663,7 +666,7 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
+ 	 * could re-enter here.
+ 	 */
+ 	pollflags = ep_call_nested(&poll_readywalk_ncalls, EP_MAX_NESTS,
+-				   ep_poll_readyevents_proc, ep, ep);
++				   ep_poll_readyevents_proc, ep, ep, current);
+ 
+ 	return pollflags != -1 ? pollflags : 0;
+ }
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 91013ff..39083e4 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -289,7 +289,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
+ 	int ret;
+ 
+ 	BUG_ON(inode->i_state & I_SYNC);
+-	WARN_ON(inode->i_state & I_NEW);
+ 
+ 	/* Set I_SYNC, reset I_DIRTY */
+ 	dirty = inode->i_state & I_DIRTY;
+@@ -314,7 +313,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
+ 	}
+ 
+ 	spin_lock(&inode_lock);
+-	WARN_ON(inode->i_state & I_NEW);
+ 	inode->i_state &= ~I_SYNC;
+ 	if (!(inode->i_state & I_FREEING)) {
+ 		if (!(inode->i_state & I_DIRTY) &&
+diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
+index bbbd5f2..41d6045 100644
+--- a/fs/jfs/jfs_extent.c
++++ b/fs/jfs/jfs_extent.c
+@@ -391,6 +391,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
+ 		}
+ 		XADaddress(xp, xaddr);
+ 		XADlength(xp, xlen);
++		XADoffset(xp, prev);
+ 		/*
+ 		 * only preserve the abnr flag within the xad flags
+ 		 * of the returned hint.
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index 79ff8d9..1a0f632 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -232,20 +232,24 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len)
+ 			"%10s => Opts: 0x%lX  AtimeQuanta: %u\n", "Mount",
+ 			osb->s_mount_opt, osb->s_atime_quantum);
+ 
+-	out += snprintf(buf + out, len - out,
+-			"%10s => Stack: %s  Name: %*s  Version: %d.%d\n",
+-			"Cluster",
+-			(*osb->osb_cluster_stack == '\0' ?
+-			 "o2cb" : osb->osb_cluster_stack),
+-			cconn->cc_namelen, cconn->cc_name,
+-			cconn->cc_version.pv_major, cconn->cc_version.pv_minor);
++	if (cconn) {
++		out += snprintf(buf + out, len - out,
++				"%10s => Stack: %s  Name: %*s  "
++				"Version: %d.%d\n", "Cluster",
++				(*osb->osb_cluster_stack == '\0' ?
++				 "o2cb" : osb->osb_cluster_stack),
++				cconn->cc_namelen, cconn->cc_name,
++				cconn->cc_version.pv_major,
++				cconn->cc_version.pv_minor);
++	}
+ 
+ 	spin_lock(&osb->dc_task_lock);
+ 	out += snprintf(buf + out, len - out,
+ 			"%10s => Pid: %d  Count: %lu  WakeSeq: %lu  "
+ 			"WorkSeq: %lu\n", "DownCnvt",
+-			task_pid_nr(osb->dc_task), osb->blocked_lock_count,
+-			osb->dc_wake_sequence, osb->dc_work_sequence);
++			(osb->dc_task ?  task_pid_nr(osb->dc_task) : -1),
++			osb->blocked_lock_count, osb->dc_wake_sequence,
++			osb->dc_work_sequence);
+ 	spin_unlock(&osb->dc_task_lock);
+ 
+ 	spin_lock(&osb->osb_lock);
+@@ -265,14 +269,15 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len)
+ 
+ 	out += snprintf(buf + out, len - out,
+ 			"%10s => Pid: %d  Interval: %lu  Needs: %d\n", "Commit",
+-			task_pid_nr(osb->commit_task), osb->osb_commit_interval,
++			(osb->commit_task ? task_pid_nr(osb->commit_task) : -1),
++			osb->osb_commit_interval,
+ 			atomic_read(&osb->needs_checkpoint));
+ 
+ 	out += snprintf(buf + out, len - out,
+-			"%10s => State: %d  NumTxns: %d  TxnId: %lu\n",
++			"%10s => State: %d  TxnId: %lu  NumTxns: %d\n",
+ 			"Journal", osb->journal->j_state,
+-			atomic_read(&osb->journal->j_num_trans),
+-			osb->journal->j_trans_id);
++			osb->journal->j_trans_id,
++			atomic_read(&osb->journal->j_num_trans));
+ 
+ 	out += snprintf(buf + out, len - out,
+ 			"%10s => GlobalAllocs: %d  LocalAllocs: %d  "
+@@ -300,7 +305,6 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len)
+ 
+ 	out += snprintf(buf + out, len - out, "%10s => %3s  %10s\n",
+ 			"Slots", "Num", "RecoGen");
+-
+ 	for (i = 0; i < osb->max_slots; ++i) {
+ 		out += snprintf(buf + out, len - out,
+ 				"%10s  %c %3d  %10d\n",
+diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
+index 3a6b193..0ff7566 100644
+--- a/fs/ramfs/inode.c
++++ b/fs/ramfs/inode.c
+@@ -202,9 +202,12 @@ static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
+ 				return -EINVAL;
+ 			opts->mode = option & S_IALLUGO;
+ 			break;
+-		default:
+-			printk(KERN_ERR "ramfs: bad mount option: %s\n", p);
+-			return -EINVAL;
++		/*
++		 * We might like to report bad mount options here;
++		 * but traditionally ramfs has ignored all mount options,
++		 * and as it is used as a !CONFIG_SHMEM simple substitute
++		 * for tmpfs, better continue to ignore other mount options.
++		 */
+ 		}
+ 	}
+ 
+diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
+index ca7c600..b5cba98 100644
+--- a/fs/xfs/xfs_bmap.c
++++ b/fs/xfs/xfs_bmap.c
+@@ -6085,6 +6085,7 @@ xfs_getbmap(
+ 			break;
+ 	}
+ 
++	kmem_free(out);
+ 	return error;
+ }
+ 
+diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h
+index cca686b..875451f 100644
+--- a/include/linux/firmware-map.h
++++ b/include/linux/firmware-map.h
+@@ -24,21 +24,17 @@
+  */
+ #ifdef CONFIG_FIRMWARE_MEMMAP
+ 
+-int firmware_map_add(resource_size_t start, resource_size_t end,
+-		     const char *type);
+-int firmware_map_add_early(resource_size_t start, resource_size_t end,
+-			   const char *type);
++int firmware_map_add(u64 start, u64 end, const char *type);
++int firmware_map_add_early(u64 start, u64 end, const char *type);
+ 
+ #else /* CONFIG_FIRMWARE_MEMMAP */
+ 
+-static inline int firmware_map_add(resource_size_t start, resource_size_t end,
+-				   const char *type)
++static inline int firmware_map_add(u64 start, u64 end, const char *type)
+ {
+ 	return 0;
+ }
+ 
+-static inline int firmware_map_add_early(resource_size_t start,
+-					 resource_size_t end, const char *type)
++static inline int firmware_map_add_early(u64 start, u64 end, const char *type)
+ {
+ 	return 0;
+ }
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index 894a56e..5eed8fa 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -125,6 +125,7 @@ struct kvm_kernel_irq_routing_entry {
+ struct kvm {
+ 	struct mutex lock; /* protects the vcpus array and APIC accesses */
+ 	spinlock_t mmu_lock;
++	spinlock_t requests_lock;
+ 	struct rw_semaphore slots_lock;
+ 	struct mm_struct *mm; /* userspace tied to this vm */
+ 	int nmemslots;
+diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
+index bf8f119..9f29d86 100644
+--- a/include/linux/mlx4/qp.h
++++ b/include/linux/mlx4/qp.h
+@@ -165,6 +165,7 @@ enum {
+ 	MLX4_WQE_CTRL_IP_CSUM		= 1 << 4,
+ 	MLX4_WQE_CTRL_TCP_UDP_CSUM	= 1 << 5,
+ 	MLX4_WQE_CTRL_INS_VLAN		= 1 << 6,
++	MLX4_WQE_CTRL_STRONG_ORDER	= 1 << 7,
+ };
+ 
+ struct mlx4_wqe_ctrl_seg {
+diff --git a/include/linux/serial.h b/include/linux/serial.h
+index 9136cc5..e5bb75a 100644
+--- a/include/linux/serial.h
++++ b/include/linux/serial.h
+@@ -96,54 +96,76 @@ struct serial_uart_config {
+ 
+ /*
+  * Definitions for async_struct (and serial_struct) flags field
++ *
++ * Define ASYNCB_* for convenient use with {test,set,clear}_bit.
+  */
+-#define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+-				   on the callout port */
+-#define ASYNC_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
+-#define ASYNC_SAK	0x0004	/* Secure Attention Key (Orange book) */
+-#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+-
+-#define ASYNC_SPD_MASK	0x1030
+-#define ASYNC_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+-
+-#define ASYNC_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+-#define ASYNC_SPD_CUST	0x0030  /* Use user-specified divisor */
+-
+-#define ASYNC_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+-#define ASYNC_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
+-#define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+-#define ASYNC_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+-#define ASYNC_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+-
+-#define ASYNC_HARDPPS_CD	0x0800	/* Call hardpps when CD goes high  */
+-
+-#define ASYNC_SPD_SHI	0x1000	/* Use 230400 instead of 38400 bps */
+-#define ASYNC_SPD_WARP	0x1010	/* Use 460800 instead of 38400 bps */
+-
+-#define ASYNC_LOW_LATENCY 0x2000 /* Request low latency behaviour */
+-
+-#define ASYNC_BUGGY_UART  0x4000 /* This is a buggy UART, skip some safety
+-				  * checks.  Note: can be dangerous! */
+-
+-#define ASYNC_AUTOPROBE	 0x8000 /* Port was autoprobed by PCI or PNP code */
+-
+-#define ASYNC_FLAGS	0x7FFF	/* Possible legal async flags */
+-#define ASYNC_USR_MASK	0x3430	/* Legal flags that non-privileged
+-				 * users can set or reset */
+-
+-/* Internal flags used only by kernel/chr_drv/serial.c */
+-#define ASYNC_INITIALIZED	0x80000000 /* Serial port was initialized */
+-#define ASYNC_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+-#define ASYNC_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+-#define ASYNC_CLOSING		0x08000000 /* Serial port is closing */
+-#define ASYNC_CTS_FLOW		0x04000000 /* Do CTS flow control */
+-#define ASYNC_CHECK_CD		0x02000000 /* i.e., CLOCAL */
+-#define ASYNC_SHARE_IRQ		0x01000000 /* for multifunction cards
+-					     --- no longer used */
+-#define ASYNC_CONS_FLOW		0x00800000 /* flow control for console  */
+-
+-#define ASYNC_BOOT_ONLYMCA	0x00400000 /* Probe only if MCA bus */
+-#define ASYNC_INTERNAL_FLAGS	0xFFC00000 /* Internal flags */
++#define ASYNCB_HUP_NOTIFY	 0 /* Notify getty on hangups and closes
++				    * on the callout port */
++#define ASYNCB_FOURPORT		 1 /* Set OU1, OUT2 per AST Fourport settings */
++#define ASYNCB_SAK		 2 /* Secure Attention Key (Orange book) */
++#define ASYNCB_SPLIT_TERMIOS	 3 /* Separate termios for dialin/callout */
++#define ASYNCB_SPD_HI		 4 /* Use 56000 instead of 38400 bps */
++#define ASYNCB_SPD_VHI		 5 /* Use 115200 instead of 38400 bps */
++#define ASYNCB_SKIP_TEST	 6 /* Skip UART test during autoconfiguration */
++#define ASYNCB_AUTO_IRQ		 7 /* Do automatic IRQ during
++				    * autoconfiguration */
++#define ASYNCB_SESSION_LOCKOUT	 8 /* Lock out cua opens based on session */
++#define ASYNCB_PGRP_LOCKOUT	 9 /* Lock out cua opens based on pgrp */
++#define ASYNCB_CALLOUT_NOHUP	10 /* Don't do hangups for cua device */
++#define ASYNCB_HARDPPS_CD	11 /* Call hardpps when CD goes high  */
++#define ASYNCB_SPD_SHI		12 /* Use 230400 instead of 38400 bps */
++#define ASYNCB_LOW_LATENCY	13 /* Request low latency behaviour */
++#define ASYNCB_BUGGY_UART	14 /* This is a buggy UART, skip some safety
++				    * checks.  Note: can be dangerous! */
++#define ASYNCB_AUTOPROBE	15 /* Port was autoprobed by PCI or PNP code */
++#define ASYNCB_LAST_USER	15
++
++/* Internal flags used only by kernel */
++#define ASYNCB_INITIALIZED	31 /* Serial port was initialized */
++#define ASYNCB_NORMAL_ACTIVE	29 /* Normal device is active */
++#define ASYNCB_BOOT_AUTOCONF	28 /* Autoconfigure port on bootup */
++#define ASYNCB_CLOSING		27 /* Serial port is closing */
++#define ASYNCB_CTS_FLOW		26 /* Do CTS flow control */
++#define ASYNCB_CHECK_CD		25 /* i.e., CLOCAL */
++#define ASYNCB_SHARE_IRQ	24 /* for multifunction cards, no longer used */
++#define ASYNCB_CONS_FLOW	23 /* flow control for console  */
++#define ASYNCB_BOOT_ONLYMCA	22 /* Probe only if MCA bus */
++#define ASYNCB_FIRST_KERNEL	22
++
++#define ASYNC_HUP_NOTIFY	(1U << ASYNCB_HUP_NOTIFY)
++#define ASYNC_FOURPORT		(1U << ASYNCB_FOURPORT)
++#define ASYNC_SAK		(1U << ASYNCB_SAK)
++#define ASYNC_SPLIT_TERMIOS	(1U << ASYNCB_SPLIT_TERMIOS)
++#define ASYNC_SPD_HI		(1U << ASYNCB_SPD_HI)
++#define ASYNC_SPD_VHI		(1U << ASYNCB_SPD_VHI)
++#define ASYNC_SKIP_TEST		(1U << ASYNCB_SKIP_TEST)
++#define ASYNC_AUTO_IRQ		(1U << ASYNCB_AUTO_IRQ)
++#define ASYNC_SESSION_LOCKOUT	(1U << ASYNCB_SESSION_LOCKOUT)
++#define ASYNC_PGRP_LOCKOUT	(1U << ASYNCB_PGRP_LOCKOUT)
++#define ASYNC_CALLOUT_NOHUP	(1U << ASYNCB_CALLOUT_NOHUP)
++#define ASYNC_HARDPPS_CD	(1U << ASYNCB_HARDPPS_CD)
++#define ASYNC_SPD_SHI		(1U << ASYNCB_SPD_SHI)
++#define ASYNC_LOW_LATENCY	(1U << ASYNCB_LOW_LATENCY)
++#define ASYNC_BUGGY_UART	(1U << ASYNCB_BUGGY_UART)
++#define ASYNC_AUTOPROBE		(1U << ASYNCB_AUTOPROBE)
++
++#define ASYNC_FLAGS		((1U << ASYNCB_LAST_USER) - 1)
++#define ASYNC_USR_MASK		(ASYNC_SPD_HI|ASYNC_SPD_VHI| \
++		ASYNC_CALLOUT_NOHUP|ASYNC_SPD_SHI|ASYNC_LOW_LATENCY)
++#define ASYNC_SPD_CUST		(ASYNC_SPD_HI|ASYNC_SPD_VHI)
++#define ASYNC_SPD_WARP		(ASYNC_SPD_HI|ASYNC_SPD_SHI)
++#define ASYNC_SPD_MASK		(ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI)
++
++#define ASYNC_INITIALIZED	(1U << ASYNCB_INITIALIZED)
++#define ASYNC_NORMAL_ACTIVE	(1U << ASYNCB_NORMAL_ACTIVE)
++#define ASYNC_BOOT_AUTOCONF	(1U << ASYNCB_BOOT_AUTOCONF)
++#define ASYNC_CLOSING		(1U << ASYNCB_CLOSING)
++#define ASYNC_CTS_FLOW		(1U << ASYNCB_CTS_FLOW)
++#define ASYNC_CHECK_CD		(1U << ASYNCB_CHECK_CD)
++#define ASYNC_SHARE_IRQ		(1U << ASYNCB_SHARE_IRQ)
++#define ASYNC_CONS_FLOW		(1U << ASYNCB_CONS_FLOW)
++#define ASYNC_BOOT_ONLYMCA	(1U << ASYNCB_BOOT_ONLYMCA)
++#define ASYNC_INTERNAL_FLAGS	(~((1U << ASYNCB_FIRST_KERNEL) - 1))
+ 
+ /*
+  * Multiport serial configuration structure --- external structure
+diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
+index 625e9e4..6d6c3b8 100644
+--- a/include/linux/usb/serial.h
++++ b/include/linux/usb/serial.h
+@@ -181,8 +181,10 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data)
+  *	This will be called when the struct usb_serial structure is fully set
+  *	set up.  Do any local initialization of the device, or any private
+  *	memory structure allocation at this point in time.
+- * @shutdown: pointer to the driver's shutdown function.  This will be
+- *	called when the device is removed from the system.
++ * @disconnect: pointer to the driver's disconnect function.  This will be
++ *	called when the device is unplugged or unbound from the driver.
++ * @release: pointer to the driver's release function.  This will be called
++ *	when the usb_serial data structure is about to be destroyed.
+  * @usb_driver: pointer to the struct usb_driver that controls this
+  *	device.  This is necessary to allow dynamic ids to be added to
+  *	the driver from sysfs.
+@@ -212,7 +214,8 @@ struct usb_serial_driver {
+ 	int (*attach)(struct usb_serial *serial);
+ 	int (*calc_num_ports) (struct usb_serial *serial);
+ 
+-	void (*shutdown)(struct usb_serial *serial);
++	void (*disconnect)(struct usb_serial *serial);
++	void (*release)(struct usb_serial *serial);
+ 
+ 	int (*port_probe)(struct usb_serial_port *port);
+ 	int (*port_remove)(struct usb_serial_port *port);
+@@ -292,7 +295,8 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
+ extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
+ extern void usb_serial_generic_throttle(struct tty_struct *tty);
+ extern void usb_serial_generic_unthrottle(struct tty_struct *tty);
+-extern void usb_serial_generic_shutdown(struct usb_serial *serial);
++extern void usb_serial_generic_disconnect(struct usb_serial *serial);
++extern void usb_serial_generic_release(struct usb_serial *serial);
+ extern int usb_serial_generic_register(int debug);
+ extern void usb_serial_generic_deregister(void);
+ 
+diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
+index 524cd1b..cfdd3ca 100644
+--- a/include/linux/vmstat.h
++++ b/include/linux/vmstat.h
+@@ -36,6 +36,9 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
+ 		FOR_ALL_ZONES(PGSTEAL),
+ 		FOR_ALL_ZONES(PGSCAN_KSWAPD),
+ 		FOR_ALL_ZONES(PGSCAN_DIRECT),
++#ifdef CONFIG_NUMA
++		PGSCAN_ZONE_RECLAIM_FAILED,
++#endif
+ 		PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL,
+ 		PAGEOUTRUN, ALLOCSTALL, PGROTATED,
+ #ifdef CONFIG_HUGETLB_PAGE
+diff --git a/include/net/x25.h b/include/net/x25.h
+index fc3f03d..2cda040 100644
+--- a/include/net/x25.h
++++ b/include/net/x25.h
+@@ -187,7 +187,7 @@ extern int  x25_addr_ntoa(unsigned char *, struct x25_address *,
+ extern int  x25_addr_aton(unsigned char *, struct x25_address *,
+ 			  struct x25_address *);
+ extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *);
+-extern void x25_destroy_socket(struct sock *);
++extern void x25_destroy_socket_from_timer(struct sock *);
+ extern int  x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int);
+ extern void x25_kill_by_neigh(struct x25_neigh *);
+ 
+diff --git a/kernel/acct.c b/kernel/acct.c
+index 7afa315..9f33910 100644
+--- a/kernel/acct.c
++++ b/kernel/acct.c
+@@ -215,6 +215,7 @@ static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file,
+ static int acct_on(char *name)
+ {
+ 	struct file *file;
++	struct vfsmount *mnt;
+ 	int error;
+ 	struct pid_namespace *ns;
+ 	struct bsd_acct_struct *acct = NULL;
+@@ -256,11 +257,12 @@ static int acct_on(char *name)
+ 		acct = NULL;
+ 	}
+ 
+-	mnt_pin(file->f_path.mnt);
++	mnt = file->f_path.mnt;
++	mnt_pin(mnt);
+ 	acct_file_reopen(ns->bacct, file, ns);
+ 	spin_unlock(&acct_lock);
+ 
+-	mntput(file->f_path.mnt); /* it's pinned, now give up active reference */
++	mntput(mnt); /* it's pinned, now give up active reference */
+ 	kfree(acct);
+ 
+ 	return 0;
+diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
+index c9a0b7d..90f1347 100644
+--- a/kernel/trace/trace_functions.c
++++ b/kernel/trace/trace_functions.c
+@@ -193,9 +193,11 @@ static void tracing_start_function_trace(void)
+ static void tracing_stop_function_trace(void)
+ {
+ 	ftrace_function_enabled = 0;
+-	/* OK if they are not registered */
+-	unregister_ftrace_function(&trace_stack_ops);
+-	unregister_ftrace_function(&trace_ops);
++
++	if (func_flags.val & TRACE_FUNC_OPT_STACK)
++		unregister_ftrace_function(&trace_stack_ops);
++	else
++		unregister_ftrace_function(&trace_ops);
+ }
+ 
+ static int func_set_flag(u32 old_flags, u32 bit, int set)
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 6cdcf38..3be4b7c 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -440,7 +440,7 @@ config LOCKDEP
+ 	bool
+ 	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
+ 	select STACKTRACE
+-	select FRAME_POINTER if !X86 && !MIPS && !PPC && !ARM_UNWIND && !S390
++	select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390
+ 	select KALLSYMS
+ 	select KALLSYMS_ALL
+ 
+diff --git a/lib/dma-debug.c b/lib/dma-debug.c
+index 69da09a..2b16536 100644
+--- a/lib/dma-debug.c
++++ b/lib/dma-debug.c
+@@ -185,15 +185,50 @@ static void put_hash_bucket(struct hash_bucket *bucket,
+ static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket,
+ 						struct dma_debug_entry *ref)
+ {
+-	struct dma_debug_entry *entry;
++	struct dma_debug_entry *entry, *ret = NULL;
++	int matches = 0, match_lvl, last_lvl = 0;
+ 
+ 	list_for_each_entry(entry, &bucket->list, list) {
+-		if ((entry->dev_addr == ref->dev_addr) &&
+-		    (entry->dev == ref->dev))
++		if ((entry->dev_addr != ref->dev_addr) ||
++		    (entry->dev != ref->dev))
++			continue;
++
++		/*
++		 * Some drivers map the same physical address multiple
++		 * times. Without a hardware IOMMU this results in the
++		 * same device addresses being put into the dma-debug
++		 * hash multiple times too. This can result in false
++		 * positives being reported. Therfore we implement a
++		 * best-fit algorithm here which returns the entry from
++		 * the hash which fits best to the reference value
++		 * instead of the first-fit.
++		 */
++		matches += 1;
++		match_lvl = 0;
++		entry->size      == ref->size      ? ++match_lvl : match_lvl;
++		entry->type      == ref->type      ? ++match_lvl : match_lvl;
++		entry->direction == ref->direction ? ++match_lvl : match_lvl;
++
++		if (match_lvl == 3) {
++			/* perfect-fit - return the result */
+ 			return entry;
++		} else if (match_lvl > last_lvl) {
++			/*
++			 * We found an entry that fits better then the
++			 * previous one
++			 */
++			last_lvl = match_lvl;
++			ret      = entry;
++		}
+ 	}
+ 
+-	return NULL;
++	/*
++	 * If we have multiple matches but no perfect-fit, just return
++	 * NULL.
++	 */
++	ret = (matches == 1) ? ret : NULL;
++
++	return ret;
+ }
+ 
+ /*
+diff --git a/lib/genalloc.c b/lib/genalloc.c
+index f6d276d..eed2bdb 100644
+--- a/lib/genalloc.c
++++ b/lib/genalloc.c
+@@ -85,7 +85,6 @@ void gen_pool_destroy(struct gen_pool *pool)
+ 	int bit, end_bit;
+ 
+ 
+-	write_lock(&pool->lock);
+ 	list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
+ 		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
+ 		list_del(&chunk->next_chunk);
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index fe753ec..f820383 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2812,7 +2812,7 @@ bad:
+ 		if (dzone == zone)
+ 			break;
+ 		kfree(zone_pcp(dzone, cpu));
+-		zone_pcp(dzone, cpu) = NULL;
++		zone_pcp(dzone, cpu) = &boot_pageset[cpu];
+ 	}
+ 	return -ENOMEM;
+ }
+@@ -2827,7 +2827,7 @@ static inline void free_zone_pagesets(int cpu)
+ 		/* Free per_cpu_pageset if it is slab allocated */
+ 		if (pset != &boot_pageset[cpu])
+ 			kfree(pset);
+-		zone_pcp(zone, cpu) = NULL;
++		zone_pcp(zone, cpu) = &boot_pageset[cpu];
+ 	}
+ }
+ 
+@@ -4501,7 +4501,7 @@ int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write,
+ 	ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+ 	if (!write || (ret == -EINVAL))
+ 		return ret;
+-	for_each_zone(zone) {
++	for_each_populated_zone(zone) {
+ 		for_each_online_cpu(cpu) {
+ 			unsigned long  high;
+ 			high = zone->present_pages / percpu_pagelist_fraction;
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index d254306..2500b01 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2290,6 +2290,48 @@ int sysctl_min_unmapped_ratio = 1;
+  */
+ int sysctl_min_slab_ratio = 5;
+ 
++static inline unsigned long zone_unmapped_file_pages(struct zone *zone)
++{
++	unsigned long file_mapped = zone_page_state(zone, NR_FILE_MAPPED);
++	unsigned long file_lru = zone_page_state(zone, NR_INACTIVE_FILE) +
++		zone_page_state(zone, NR_ACTIVE_FILE);
++
++	/*
++	 * It's possible for there to be more file mapped pages than
++	 * accounted for by the pages on the file LRU lists because
++	 * tmpfs pages accounted for as ANON can also be FILE_MAPPED
++	 */
++	return (file_lru > file_mapped) ? (file_lru - file_mapped) : 0;
++}
++
++/* Work out how many page cache pages we can reclaim in this reclaim_mode */
++static long zone_pagecache_reclaimable(struct zone *zone)
++{
++	long nr_pagecache_reclaimable;
++	long delta = 0;
++
++	/*
++	 * If RECLAIM_SWAP is set, then all file pages are considered
++	 * potentially reclaimable. Otherwise, we have to worry about
++	 * pages like swapcache and zone_unmapped_file_pages() provides
++	 * a better estimate
++	 */
++	if (zone_reclaim_mode & RECLAIM_SWAP)
++		nr_pagecache_reclaimable = zone_page_state(zone, NR_FILE_PAGES);
++	else
++		nr_pagecache_reclaimable = zone_unmapped_file_pages(zone);
++
++	/* If we can't clean pages, remove dirty pages from consideration */
++	if (!(zone_reclaim_mode & RECLAIM_WRITE))
++		delta += zone_page_state(zone, NR_FILE_DIRTY);
++
++	/* Watch for any possible underflows due to delta */
++	if (unlikely(delta > nr_pagecache_reclaimable))
++		delta = nr_pagecache_reclaimable;
++
++	return nr_pagecache_reclaimable - delta;
++}
++
+ /*
+  * Try to free up some pages from this zone through reclaim.
+  */
+@@ -2324,9 +2366,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
+ 	reclaim_state.reclaimed_slab = 0;
+ 	p->reclaim_state = &reclaim_state;
+ 
+-	if (zone_page_state(zone, NR_FILE_PAGES) -
+-		zone_page_state(zone, NR_FILE_MAPPED) >
+-		zone->min_unmapped_pages) {
++	if (zone_pagecache_reclaimable(zone) > zone->min_unmapped_pages) {
+ 		/*
+ 		 * Free memory by calling shrink zone with increasing
+ 		 * priorities until we have enough memory freed.
+@@ -2384,10 +2424,8 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
+ 	 * if less than a specified percentage of the zone is used by
+ 	 * unmapped file backed pages.
+ 	 */
+-	if (zone_page_state(zone, NR_FILE_PAGES) -
+-	    zone_page_state(zone, NR_FILE_MAPPED) <= zone->min_unmapped_pages
+-	    && zone_page_state(zone, NR_SLAB_RECLAIMABLE)
+-			<= zone->min_slab_pages)
++	if (zone_pagecache_reclaimable(zone) <= zone->min_unmapped_pages &&
++	    zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages)
+ 		return 0;
+ 
+ 	if (zone_is_all_unreclaimable(zone))
+@@ -2414,6 +2452,9 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
+ 	ret = __zone_reclaim(zone, gfp_mask, order);
+ 	zone_clear_flag(zone, ZONE_RECLAIM_LOCKED);
+ 
++	if (!ret)
++		count_vm_event(PGSCAN_ZONE_RECLAIM_FAILED);
++
+ 	return ret;
+ }
+ #endif
+diff --git a/mm/vmstat.c b/mm/vmstat.c
+index 74d66db..ddb360a 100644
+--- a/mm/vmstat.c
++++ b/mm/vmstat.c
+@@ -675,6 +675,9 @@ static const char * const vmstat_text[] = {
+ 	TEXTS_FOR_ZONES("pgscan_kswapd")
+ 	TEXTS_FOR_ZONES("pgscan_direct")
+ 
++#ifdef CONFIG_NUMA
++	"zone_reclaim_failed",
++#endif
+ 	"pginodesteal",
+ 	"slabs_scanned",
+ 	"kswapd_steal",
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 28205e5..d777f84 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1081,8 +1081,35 @@ restart:
+ 	now = jiffies;
+ 
+ 	if (!rt_caching(dev_net(rt->u.dst.dev))) {
+-		rt_drop(rt);
+-		return 0;
++		/*
++		 * If we're not caching, just tell the caller we
++		 * were successful and don't touch the route.  The
++		 * caller hold the sole reference to the cache entry, and
++		 * it will be released when the caller is done with it.
++		 * If we drop it here, the callers have no way to resolve routes
++		 * when we're not caching.  Instead, just point *rp at rt, so
++		 * the caller gets a single use out of the route
++		 * Note that we do rt_free on this new route entry, so that
++		 * once its refcount hits zero, we are still able to reap it
++		 * (Thanks Alexey)
++		 * Note also the rt_free uses call_rcu.  We don't actually
++		 * need rcu protection here, this is just our path to get
++		 * on the route gc list.
++		 */
++
++		if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
++			int err = arp_bind_neighbour(&rt->u.dst);
++			if (err) {
++				if (net_ratelimit())
++					printk(KERN_WARNING
++					    "Neighbour table failure & not caching routes.\n");
++				rt_drop(rt);
++				return err;
++			}
++		}
++
++		rt_free(rt);
++		goto skip_hashing;
+ 	}
+ 
+ 	rthp = &rt_hash_table[hash].chain;
+@@ -1196,7 +1223,8 @@ restart:
+ #if RT_CACHE_DEBUG >= 2
+ 	if (rt->u.dst.rt_next) {
+ 		struct rtable *trt;
+-		printk(KERN_DEBUG "rt_cache @%02x: %pI4", hash, &rt->rt_dst);
++		printk(KERN_DEBUG "rt_cache @%02x: %pI4",
++		       hash, &rt->rt_dst);
+ 		for (trt = rt->u.dst.rt_next; trt; trt = trt->u.dst.rt_next)
+ 			printk(" . %pI4", &trt->rt_dst);
+ 		printk("\n");
+@@ -1210,6 +1238,8 @@ restart:
+ 	rcu_assign_pointer(rt_hash_table[hash].chain, rt);
+ 
+ 	spin_unlock_bh(rt_hash_lock_addr(hash));
++
++skip_hashing:
+ 	*rp = rt;
+ 	return 0;
+ }
+diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
+index d9233ec..2681dfa 100644
+--- a/net/mac80211/rc80211_minstrel.c
++++ b/net/mac80211/rc80211_minstrel.c
+@@ -216,7 +216,7 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi)
+ 	unsigned int sample_ndx;
+ 	sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column);
+ 	mi->sample_idx++;
+-	if (mi->sample_idx > (mi->n_rates - 2)) {
++	if ((int) mi->sample_idx > (mi->n_rates - 2)) {
+ 		mi->sample_idx = 0;
+ 		mi->sample_column++;
+ 		if (mi->sample_column >= SAMPLE_COLUMNS)
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 2456e4e..b759106 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -2385,18 +2385,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
+ 			rem_reg_rules) {
+ 		num_rules++;
+ 		if (num_rules > NL80211_MAX_SUPP_REG_RULES)
+-			goto bad_reg;
++			return -EINVAL;
+ 	}
+ 
+-	if (!reg_is_valid_request(alpha2))
+-		return -EINVAL;
++	mutex_lock(&cfg80211_mutex);
++
++	if (!reg_is_valid_request(alpha2)) {
++		r = -EINVAL;
++		goto bad_reg;
++	}
+ 
+ 	size_of_regd = sizeof(struct ieee80211_regdomain) +
+ 		(num_rules * sizeof(struct ieee80211_reg_rule));
+ 
+ 	rd = kzalloc(size_of_regd, GFP_KERNEL);
+-	if (!rd)
+-		return -ENOMEM;
++	if (!rd) {
++		r = -ENOMEM;
++		goto bad_reg;
++	}
+ 
+ 	rd->n_reg_rules = num_rules;
+ 	rd->alpha2[0] = alpha2[0];
+@@ -2413,20 +2419,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
+ 
+ 		rule_idx++;
+ 
+-		if (rule_idx > NL80211_MAX_SUPP_REG_RULES)
++		if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
++			r = -EINVAL;
+ 			goto bad_reg;
++		}
+ 	}
+ 
+ 	BUG_ON(rule_idx != num_rules);
+ 
+-	mutex_lock(&cfg80211_mutex);
+ 	r = set_regdom(rd);
++
+ 	mutex_unlock(&cfg80211_mutex);
++
+ 	return r;
+ 
+  bad_reg:
++	mutex_unlock(&cfg80211_mutex);
+ 	kfree(rd);
+-	return -EINVAL;
++	return r;
+ }
+ 
+ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 487cb62..9765bc8 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -389,6 +389,8 @@ static int call_crda(const char *alpha2)
+ /* Used by nl80211 before kmalloc'ing our regulatory domain */
+ bool reg_is_valid_request(const char *alpha2)
+ {
++	assert_cfg80211_lock();
++
+ 	if (!last_request)
+ 		return false;
+ 
+@@ -2042,7 +2044,13 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
+ 	 * the country IE rd with what CRDA believes that country should have
+ 	 */
+ 
+-	BUG_ON(!country_ie_regdomain);
++	/*
++	 * Userspace could have sent two replies with only
++	 * one kernel request. By the second reply we would have
++	 * already processed and consumed the country_ie_regdomain.
++	 */
++	if (!country_ie_regdomain)
++		return -EALREADY;
+ 	BUG_ON(rd == country_ie_regdomain);
+ 
+ 	/*
+diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
+index ed80af8..c51f309 100644
+--- a/net/x25/af_x25.c
++++ b/net/x25/af_x25.c
+@@ -332,14 +332,14 @@ static unsigned int x25_new_lci(struct x25_neigh *nb)
+ /*
+  *	Deferred destroy.
+  */
+-void x25_destroy_socket(struct sock *);
++static void __x25_destroy_socket(struct sock *);
+ 
+ /*
+  *	handler for deferred kills.
+  */
+ static void x25_destroy_timer(unsigned long data)
+ {
+-	x25_destroy_socket((struct sock *)data);
++	x25_destroy_socket_from_timer((struct sock *)data);
+ }
+ 
+ /*
+@@ -349,12 +349,10 @@ static void x25_destroy_timer(unsigned long data)
+  *	will touch it and we are (fairly 8-) ) safe.
+  *	Not static as it's used by the timer
+  */
+-void x25_destroy_socket(struct sock *sk)
++static void __x25_destroy_socket(struct sock *sk)
+ {
+ 	struct sk_buff *skb;
+ 
+-	sock_hold(sk);
+-	lock_sock(sk);
+ 	x25_stop_heartbeat(sk);
+ 	x25_stop_timer(sk);
+ 
+@@ -385,7 +383,22 @@ void x25_destroy_socket(struct sock *sk)
+ 		/* drop last reference so sock_put will free */
+ 		__sock_put(sk);
+ 	}
++}
+ 
++void x25_destroy_socket_from_timer(struct sock *sk)
++{
++	sock_hold(sk);
++	bh_lock_sock(sk);
++	__x25_destroy_socket(sk);
++	bh_unlock_sock(sk);
++	sock_put(sk);
++}
++
++static void x25_destroy_socket(struct sock *sk)
++{
++	sock_hold(sk);
++	lock_sock(sk);
++	__x25_destroy_socket(sk);
+ 	release_sock(sk);
+ 	sock_put(sk);
+ }
+diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c
+index d3e3e54..5c5db1a 100644
+--- a/net/x25/x25_timer.c
++++ b/net/x25/x25_timer.c
+@@ -113,7 +113,7 @@ static void x25_heartbeat_expiry(unsigned long param)
+ 			    (sk->sk_state == TCP_LISTEN &&
+ 			     sock_flag(sk, SOCK_DEAD))) {
+ 				bh_unlock_sock(sk);
+-				x25_destroy_socket(sk);
++				x25_destroy_socket_from_timer(sk);
+ 				return;
+ 			}
+ 			break;
+diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
+index 1e082bb..97a80fb 100644
+--- a/security/integrity/ima/ima_audit.c
++++ b/security/integrity/ima/ima_audit.c
+@@ -50,7 +50,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
+ 
+ 	ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
+ 	audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u ses=%u",
+-			 current->pid, current->cred->uid,
++			 current->pid, current_cred()->uid,
+ 			 audit_get_loginuid(current),
+ 			 audit_get_sessionid(current));
+ 	audit_log_task_context(ab);
+diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
+index f4e7266..88407e5 100644
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -128,10 +128,6 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
+ {
+ 	int rc = 0;
+ 
+-	if (IS_ERR(file)) {
+-		pr_info("%s dentry_open failed\n", filename);
+-		return rc;
+-	}
+ 	iint->opencount++;
+ 	iint->readcount++;
+ 
+@@ -196,7 +192,14 @@ int ima_path_check(struct path *path, int mask)
+ 		struct dentry *dentry = dget(path->dentry);
+ 		struct vfsmount *mnt = mntget(path->mnt);
+ 
+-		file = dentry_open(dentry, mnt, O_RDONLY, current->cred);
++		file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
++				   current_cred());
++		if (IS_ERR(file)) {
++			pr_info("%s dentry_open failed\n", dentry->d_name.name);
++			rc = PTR_ERR(file);
++			file = NULL;
++			goto out;
++		}
+ 		rc = get_path_measurement(iint, file, dentry->d_name.name);
+ 	}
+ out:
+diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
+index 8284f17..b5d6ea4 100644
+--- a/sound/core/seq/seq_midi_event.c
++++ b/sound/core/seq/seq_midi_event.c
+@@ -504,10 +504,10 @@ static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
+ 	if (dev->nostat && count < 12)
+ 		return -ENOMEM;
+ 	cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
+-	bytes[0] = ev->data.control.param & 0x007f;
+-	bytes[1] = (ev->data.control.param & 0x3f80) >> 7;
+-	bytes[2] = ev->data.control.value & 0x007f;
+-	bytes[3] = (ev->data.control.value & 0x3f80) >> 7;
++	bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
++	bytes[1] = ev->data.control.param & 0x007f;
++	bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
++	bytes[3] = ev->data.control.value & 0x007f;
+ 	if (cmd != dev->lastcmd && !dev->nostat) {
+ 		if (count < 9)
+ 			return -ENOMEM;
+diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
+index de83608..3ee0269 100644
+--- a/sound/isa/cmi8330.c
++++ b/sound/isa/cmi8330.c
+@@ -338,7 +338,7 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
+ 		return -EBUSY;
+ 
+ 	acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
+-	if (acard->play == NULL)
++	if (acard->mpu == NULL)
+ 		return -EBUSY;
+ 
+ 	pdev = acard->cap;
+diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
+index c111efe..f143f71 100644
+--- a/sound/pci/ca0106/ca0106_mixer.c
++++ b/sound/pci/ca0106/ca0106_mixer.c
+@@ -841,6 +841,9 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
+ 					      snd_ca0106_master_db_scale);
+ 	if (!vmaster)
+ 		return -ENOMEM;
++	err = snd_ctl_add(card, vmaster);
++	if (err < 0)
++		return err;
+ 	add_slaves(card, vmaster, slave_vols);
+ 
+ 	if (emu->details->spi_dac == 1) {
+@@ -848,6 +851,9 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
+ 						      NULL);
+ 		if (!vmaster)
+ 			return -ENOMEM;
++		err = snd_ctl_add(card, vmaster);
++		if (err < 0)
++			return err;
+ 		add_slaves(card, vmaster, slave_sws);
+ 	}
+         return 0;
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 0fd258e..f09324a 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10915,6 +10915,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
+ 	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
+ 	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
+ 	SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
++	SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
+ 	SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
+ 			   ALC262_SONY_ASSAMD),
+ 	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
+@@ -11122,6 +11123,7 @@ static struct alc_config_preset alc262_presets[] = {
+ 		.capsrc_nids = alc262_dmic_capsrc_nids,
+ 		.dac_nids = alc262_dac_nids,
+ 		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
++		.num_adc_nids = 1, /* single ADC */
+ 		.dig_out_nid = ALC262_DIGOUT_NID,
+ 		.num_channel_mode = ARRAY_SIZE(alc262_modes),
+ 		.channel_mode = alc262_modes,
+diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
+index 173bebf..8aa5687 100644
+--- a/sound/pci/intel8x0.c
++++ b/sound/pci/intel8x0.c
+@@ -356,8 +356,6 @@ struct ichdev {
+         unsigned int position;
+ 	unsigned int pos_shift;
+ 	unsigned int last_pos;
+-	unsigned long last_pos_jiffies;
+-	unsigned int jiffy_to_bytes;
+         int frags;
+         int lvi;
+         int lvi_frag;
+@@ -844,7 +842,6 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd
+ 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ 		val = ICH_IOCE | ICH_STARTBM;
+ 		ichdev->last_pos = ichdev->position;
+-		ichdev->last_pos_jiffies = jiffies;
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_SUSPEND:
+ 		ichdev->suspended = 1;
+@@ -1048,7 +1045,6 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream)
+ 			ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
+ 	}
+ 	snd_intel8x0_setup_periods(chip, ichdev);
+-	ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ;
+ 	return 0;
+ }
+ 
+@@ -1073,19 +1069,23 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
+ 		    ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
+ 			break;
+ 	} while (timeout--);
++	ptr = ichdev->last_pos;
+ 	if (ptr1 != 0) {
+ 		ptr1 <<= ichdev->pos_shift;
+ 		ptr = ichdev->fragsize1 - ptr1;
+ 		ptr += position;
+-		ichdev->last_pos = ptr;
+-		ichdev->last_pos_jiffies = jiffies;
+-	} else {
+-		ptr1 = jiffies - ichdev->last_pos_jiffies;
+-		if (ptr1)
+-			ptr1 -= 1;
+-		ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes;
+-		ptr %= ichdev->size;
++		if (ptr < ichdev->last_pos) {
++			unsigned int pos_base, last_base;
++			pos_base = position / ichdev->fragsize1;
++			last_base = ichdev->last_pos / ichdev->fragsize1;
++			/* another sanity check; ptr1 can go back to full
++			 * before the base position is updated
++			 */
++			if (pos_base == last_base)
++				ptr = ichdev->last_pos;
++		}
+ 	}
++	ichdev->last_pos = ptr;
+ 	spin_unlock(&chip->reg_lock);
+ 	if (ptr >= ichdev->size)
+ 		return 0;
+diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
+index 8cf571f..39805ce 100644
+--- a/sound/soc/codecs/wm8903.c
++++ b/sound/soc/codecs/wm8903.c
+@@ -1215,22 +1215,18 @@ static struct {
+ 	int div;
+ } bclk_divs[] = {
+ 	{  10,  0 },
+-	{  15,  1 },
+ 	{  20,  2 },
+ 	{  30,  3 },
+ 	{  40,  4 },
+ 	{  50,  5 },
+-	{  55,  6 },
+ 	{  60,  7 },
+ 	{  80,  8 },
+ 	{ 100,  9 },
+-	{ 110, 10 },
+ 	{ 120, 11 },
+ 	{ 160, 12 },
+ 	{ 200, 13 },
+ 	{ 220, 14 },
+ 	{ 240, 15 },
+-	{ 250, 16 },
+ 	{ 300, 17 },
+ 	{ 320, 18 },
+ 	{ 440, 19 },
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 4d0dd39..1489829 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -581,6 +581,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
+ 		cpumask_clear(cpus);
+ 
+ 	me = get_cpu();
++	spin_lock(&kvm->requests_lock);
+ 	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+ 		vcpu = kvm->vcpus[i];
+ 		if (!vcpu)
+@@ -597,6 +598,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
+ 		smp_call_function_many(cpus, ack_flush, NULL, 1);
+ 	else
+ 		called = false;
++	spin_unlock(&kvm->requests_lock);
+ 	put_cpu();
+ 	free_cpumask_var(cpus);
+ 	return called;
+@@ -817,6 +819,7 @@ static struct kvm *kvm_create_vm(void)
+ 	kvm->mm = current->mm;
+ 	atomic_inc(&kvm->mm->mm_count);
+ 	spin_lock_init(&kvm->mmu_lock);
++	spin_lock_init(&kvm->requests_lock);
+ 	kvm_io_bus_init(&kvm->pio_bus);
+ 	mutex_init(&kvm->lock);
+ 	kvm_io_bus_init(&kvm->mmio_bus);
+@@ -919,9 +922,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
+ {
+ 	int r;
+ 	gfn_t base_gfn;
+-	unsigned long npages;
+-	int largepages;
+-	unsigned long i;
++	unsigned long npages, ugfn;
++	unsigned long largepages, i;
+ 	struct kvm_memory_slot *memslot;
+ 	struct kvm_memory_slot old, new;
+ 
+@@ -1010,6 +1012,14 @@ int __kvm_set_memory_region(struct kvm *kvm,
+ 			new.lpage_info[0].write_count = 1;
+ 		if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE)
+ 			new.lpage_info[largepages-1].write_count = 1;
++		ugfn = new.userspace_addr >> PAGE_SHIFT;
++		/*
++		 * If the gfn and userspace address are not aligned wrt each
++		 * other, disable large page support for this slot
++		 */
++		if ((base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE - 1))
++			for (i = 0; i < largepages; ++i)
++				new.lpage_info[i].write_count = 1;
+ 	}
+ 
+ 	/* Allocate page dirty bitmap if needed */
+@@ -1020,6 +1030,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
+ 		if (!new.dirty_bitmap)
+ 			goto out_free;
+ 		memset(new.dirty_bitmap, 0, dirty_bytes);
++		if (old.npages)
++			kvm_arch_flush_shadow(kvm);
+ 	}
+ #endif /* not defined CONFIG_S390 */
+ 

Added: dists/sid/linux-2.6/debian/patches/series/2
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/series/2	Fri Jul  3 15:05:53 2009	(r13863)
@@ -0,0 +1,2 @@
+- bugfix/all/0001-xfs-fix-freeing-memory-in-xfs_getbmap.patch
++ bugfix/all/stable/2.6.30.1.patch



More information about the Kernel-svn-changes mailing list