[kernel] r14339 - in dists/trunk/linux-2.6/debian: . patches/bugfix/all/stable patches/series
Maximilian Attems
maks at alioth.debian.org
Mon Oct 5 21:55:45 UTC 2009
Author: maks
Date: Mon Oct 5 21:55:43 2009
New Revision: 14339
Log:
add stable 2.6.31.2
Added:
dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.31.2.patch
Modified:
dists/trunk/linux-2.6/debian/changelog
dists/trunk/linux-2.6/debian/patches/series/base
Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog Mon Oct 5 03:18:36 2009 (r14338)
+++ dists/trunk/linux-2.6/debian/changelog Mon Oct 5 21:55:43 2009 (r14339)
@@ -10,6 +10,9 @@
(Closes: #549002)
* Add support for DEB_BUILD_OPTIONS=parallel=N (Closes: #458560)
+ [ maximilian attems ]
+ * Add stable release 2.6.31.2.
+
-- Ben Hutchings <ben at decadent.org.uk> Sun, 04 Oct 2009 19:48:35 +0100
linux-2.6 (2.6.31-1~experimental.1) experimental; urgency=low
Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.31.2.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/2.6.31.2.patch Mon Oct 5 21:55:43 2009 (r14339)
@@ -0,0 +1,7459 @@
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 8dca9d8..2ccc21c 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -897,6 +897,12 @@ W: http://wireless.kernel.org/en/users/Drivers/ar9170
+ S: Maintained
+ F: drivers/net/wireless/ath/ar9170/
+
++ATK0110 HWMON DRIVER
++M: Luca Tettamanti <kronos.it at gmail.com>
++L: lm-sensors at lm-sensors.org
++S: Maintained
++F: drivers/hwmon/asus_atk0110.c
++
+ ATI_REMOTE2 DRIVER
+ M: Ville Syrjala <syrjala at sci.fi>
+ S: Maintained
+diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
+index e302dae..8e059e5 100644
+--- a/arch/alpha/kernel/core_marvel.c
++++ b/arch/alpha/kernel/core_marvel.c
+@@ -1016,7 +1016,7 @@ marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *m
+ {
+ struct marvel_agp_aperture *aper = agp->aperture.sysdata;
+ return iommu_bind(aper->arena, aper->pg_start + pg_start,
+- mem->page_count, mem->memory);
++ mem->page_count, mem->pages);
+ }
+
+ static int
+diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
+index 319fcb7..7668649 100644
+--- a/arch/alpha/kernel/core_titan.c
++++ b/arch/alpha/kernel/core_titan.c
+@@ -680,7 +680,7 @@ titan_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *me
+ {
+ struct titan_agp_aperture *aper = agp->aperture.sysdata;
+ return iommu_bind(aper->arena, aper->pg_start + pg_start,
+- mem->page_count, mem->memory);
++ mem->page_count, mem->pages);
+ }
+
+ static int
+diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
+index 00edd04..85457b2 100644
+--- a/arch/alpha/kernel/pci_impl.h
++++ b/arch/alpha/kernel/pci_impl.h
+@@ -198,7 +198,7 @@ extern unsigned long size_for_memory(unsigned long max);
+
+ extern int iommu_reserve(struct pci_iommu_arena *, long, long);
+ extern int iommu_release(struct pci_iommu_arena *, long, long);
+-extern int iommu_bind(struct pci_iommu_arena *, long, long, unsigned long *);
++extern int iommu_bind(struct pci_iommu_arena *, long, long, struct page **);
+ extern int iommu_unbind(struct pci_iommu_arena *, long, long);
+
+
+diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
+index bfb880a..eadd63b 100644
+--- a/arch/alpha/kernel/pci_iommu.c
++++ b/arch/alpha/kernel/pci_iommu.c
+@@ -880,7 +880,7 @@ iommu_release(struct pci_iommu_arena *arena, long pg_start, long pg_count)
+
+ int
+ iommu_bind(struct pci_iommu_arena *arena, long pg_start, long pg_count,
+- unsigned long *physaddrs)
++ struct page **pages)
+ {
+ unsigned long flags;
+ unsigned long *ptes;
+@@ -900,7 +900,7 @@ iommu_bind(struct pci_iommu_arena *arena, long pg_start, long pg_count,
+ }
+
+ for(i = 0, j = pg_start; i < pg_count; i++, j++)
+- ptes[j] = mk_iommu_pte(physaddrs[i]);
++ ptes[j] = mk_iommu_pte(page_to_phys(pages[i]));
+
+ spin_unlock_irqrestore(&arena->lock, flags);
+
+diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
+index 2546c06..629e05d 100644
+--- a/arch/arm/mach-pxa/sharpsl_pm.c
++++ b/arch/arm/mach-pxa/sharpsl_pm.c
+@@ -678,8 +678,8 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab
+ dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
+ }
+
+- if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) )
+- {
++ if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) ||
++ (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) {
+ dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
+ corgi_goto_sleep(alarm_time, alarm_enable, state);
+ return 1;
+diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
+index a7e210b..0cd2e34 100644
+--- a/arch/powerpc/include/asm/pte-common.h
++++ b/arch/powerpc/include/asm/pte-common.h
+@@ -176,7 +176,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
+ #define HAVE_PAGE_AGP
+
+ /* Advertise support for _PAGE_SPECIAL */
+-#ifdef _PAGE_SPECIAL
++#if _PAGE_SPECIAL != 0
+ #define __HAVE_ARCH_PTE_SPECIAL
+ #endif
+
+diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
+index 627767d..d8e6725 100644
+--- a/arch/powerpc/mm/pgtable.c
++++ b/arch/powerpc/mm/pgtable.c
+@@ -30,6 +30,8 @@
+ #include <asm/tlbflush.h>
+ #include <asm/tlb.h>
+
++#include "mmu_decl.h"
++
+ static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
+ static unsigned long pte_freelist_forced_free;
+
+@@ -119,7 +121,7 @@ void pte_free_finish(void)
+ /*
+ * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
+ */
+-static pte_t do_dcache_icache_coherency(pte_t pte)
++static pte_t do_dcache_icache_coherency(pte_t pte, unsigned long addr)
+ {
+ unsigned long pfn = pte_pfn(pte);
+ struct page *page;
+@@ -128,6 +130,17 @@ static pte_t do_dcache_icache_coherency(pte_t pte)
+ return pte;
+ page = pfn_to_page(pfn);
+
++#ifdef CONFIG_8xx
++ /* On 8xx, cache control instructions (particularly
++ * "dcbst" from flush_dcache_icache) fault as write
++ * operation if there is an unpopulated TLB entry
++ * for the address in question. To workaround that,
++ * we invalidate the TLB here, thus avoiding dcbst
++ * misbehaviour.
++ */
++ _tlbil_va(addr, 0 /* 8xx doesn't care about PID */);
++#endif
++
+ if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
+ pr_devel("do_dcache_icache_coherency... flushing\n");
+ flush_dcache_icache_page(page);
+@@ -198,7 +211,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte
+ */
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ if (pte_need_exec_flush(pte, 1))
+- pte = do_dcache_icache_coherency(pte);
++ pte = do_dcache_icache_coherency(pte, addr);
+
+ /* Perform the setting of the PTE */
+ __set_pte_at(mm, addr, ptep, pte, 0);
+@@ -216,7 +229,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+ {
+ int changed;
+ if (!dirty && pte_need_exec_flush(entry, 0))
+- entry = do_dcache_icache_coherency(entry);
++ entry = do_dcache_icache_coherency(entry, address);
+ changed = !pte_same(*(ptep), entry);
+ if (changed) {
+ if (!(vma->vm_flags & VM_HUGETLB))
+diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
+index 83c1bc8..456a304 100644
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -299,6 +299,8 @@ do { \
+
+ #ifdef CONFIG_X86_32
+
++#define STACK_RND_MASK (0x7ff)
++
+ #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
+
+ #define ARCH_DLINFO ARCH_DLINFO_IA32(vdso_enabled)
+diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
+index 77a6850..03a0cbd 100644
+--- a/arch/x86/include/asm/uv/uv_hub.h
++++ b/arch/x86/include/asm/uv/uv_hub.h
+@@ -422,7 +422,7 @@ static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
+ unsigned long val;
+
+ val = (1UL << UVH_IPI_INT_SEND_SHFT) |
+- ((apicid & 0x3f) << UVH_IPI_INT_APIC_ID_SHFT) |
++ ((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
+ (vector << UVH_IPI_INT_VECTOR_SHFT);
+ uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+ }
+diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+index 2a50ef8..fde0cd3 100644
+--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
++++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+@@ -605,9 +605,10 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
+ return 0;
+ }
+
+-static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
++static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
++ unsigned int entry)
+ {
+- data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
++ powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+ }
+
+ static void print_basics(struct powernow_k8_data *data)
+@@ -914,13 +915,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
+ "bad value %d.\n", i, index);
+ printk(KERN_ERR PFX "Please report to BIOS "
+ "manufacturer\n");
+- invalidate_entry(data, i);
++ invalidate_entry(powernow_table, i);
+ continue;
+ }
+ rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
+ if (!(hi & HW_PSTATE_VALID_MASK)) {
+ dprintk("invalid pstate %d, ignoring\n", index);
+- invalidate_entry(data, i);
++ invalidate_entry(powernow_table, i);
+ continue;
+ }
+
+@@ -970,7 +971,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
+ /* verify frequency is OK */
+ if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
+ dprintk("invalid freq %u kHz, ignoring\n", freq);
+- invalidate_entry(data, i);
++ invalidate_entry(powernow_table, i);
+ continue;
+ }
+
+@@ -978,7 +979,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
+ * BIOSs are using "off" to indicate invalid */
+ if (vid == VID_OFF) {
+ dprintk("invalid vid %u, ignoring\n", vid);
+- invalidate_entry(data, i);
++ invalidate_entry(powernow_table, i);
+ continue;
+ }
+
+@@ -997,7 +998,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
+
+ dprintk("double low frequency table entry, "
+ "ignoring it.\n");
+- invalidate_entry(data, i);
++ invalidate_entry(powernow_table, i);
+ continue;
+ } else
+ cntlofreq = i;
+@@ -1009,7 +1010,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
+ (unsigned int)
+ (data->acpi_data.states[i].core_frequency
+ * 1000));
+- invalidate_entry(data, i);
++ invalidate_entry(powernow_table, i);
+ continue;
+ }
+ }
+diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
+index a5cdb35..4712293 100644
+--- a/arch/x86/kvm/mmu.c
++++ b/arch/x86/kvm/mmu.c
+@@ -2713,12 +2713,6 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
+
+ ASSERT(vcpu);
+
+- if (vcpu->kvm->arch.n_requested_mmu_pages)
+- vcpu->kvm->arch.n_free_mmu_pages =
+- vcpu->kvm->arch.n_requested_mmu_pages;
+- else
+- vcpu->kvm->arch.n_free_mmu_pages =
+- vcpu->kvm->arch.n_alloc_mmu_pages;
+ /*
+ * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.
+ * Therefore we need to allocate shadow page tables in the first
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index b5fa966..6a768ff 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1569,7 +1569,6 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
+ vcpu->arch.cr0 = cr0;
+ vmx_set_cr4(vcpu, vcpu->arch.cr4);
+ *hw_cr0 |= X86_CR0_PE | X86_CR0_PG;
+- *hw_cr0 &= ~X86_CR0_WP;
+ } else if (!is_paging(vcpu)) {
+ /* From nonpaging to paging */
+ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
+@@ -1578,9 +1577,10 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
+ CPU_BASED_CR3_STORE_EXITING));
+ vcpu->arch.cr0 = cr0;
+ vmx_set_cr4(vcpu, vcpu->arch.cr4);
+- if (!(vcpu->arch.cr0 & X86_CR0_WP))
+- *hw_cr0 &= ~X86_CR0_WP;
+ }
++
++ if (!(cr0 & X86_CR0_WP))
++ *hw_cr0 &= ~X86_CR0_WP;
+ }
+
+ static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 3d36045..91a077f 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1448,6 +1448,10 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
+ for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
+ do_cpuid_ent(&cpuid_entries[nent], func, 0,
+ &nent, cpuid->nent);
++ r = -E2BIG;
++ if (nent >= cpuid->nent)
++ goto out_free;
++
+ r = -EFAULT;
+ if (copy_to_user(entries, cpuid_entries,
+ nent * sizeof(struct kvm_cpuid_entry2)))
+@@ -3198,6 +3202,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
+ if (!kvm_x86_ops->update_cr8_intercept)
+ return;
+
++ if (!vcpu->arch.apic)
++ return;
++
+ if (!vcpu->arch.apic->vapic_addr)
+ max_irr = kvm_lapic_find_highest_irr(vcpu);
+ else
+@@ -4118,13 +4125,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+
+ vcpu->arch.cr2 = sregs->cr2;
+ mmu_reset_needed |= 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);
++ vcpu->arch.cr3 = sregs->cr3;
+
+ kvm_set_cr8(vcpu, sregs->cr8);
+
+diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
+index eefdeee..0088329 100644
+--- a/arch/x86/mm/Makefile
++++ b/arch/x86/mm/Makefile
+@@ -1,6 +1,11 @@
+ obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
+ pat.o pgtable.o gup.o
+
++# Make sure __phys_addr has no stackprotector
++nostackp := $(call cc-option, -fno-stack-protector)
++CFLAGS_ioremap.o := $(nostackp)
++CFLAGS_init.o := $(nostackp)
++
+ obj-$(CONFIG_SMP) += tlb.o
+
+ obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o
+diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
+index 1658296..c8191de 100644
+--- a/arch/x86/mm/mmap.c
++++ b/arch/x86/mm/mmap.c
+@@ -29,13 +29,26 @@
+ #include <linux/random.h>
+ #include <linux/limits.h>
+ #include <linux/sched.h>
++#include <asm/elf.h>
++
++static unsigned int stack_maxrandom_size(void)
++{
++ unsigned int max = 0;
++ if ((current->flags & PF_RANDOMIZE) &&
++ !(current->personality & ADDR_NO_RANDOMIZE)) {
++ max = ((-1U) & STACK_RND_MASK) << PAGE_SHIFT;
++ }
++
++ return max;
++}
++
+
+ /*
+ * Top of mmap area (just below the process stack).
+ *
+- * Leave an at least ~128 MB hole.
++ * Leave an at least ~128 MB hole with possible stack randomization.
+ */
+-#define MIN_GAP (128*1024*1024)
++#define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
+ #define MAX_GAP (TASK_SIZE/6*5)
+
+ /*
+diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
+index e245775..fbb46d6 100644
+--- a/arch/x86/mm/pageattr.c
++++ b/arch/x86/mm/pageattr.c
+@@ -143,6 +143,7 @@ void clflush_cache_range(void *vaddr, unsigned int size)
+
+ mb();
+ }
++EXPORT_SYMBOL_GPL(clflush_cache_range);
+
+ static void __cpa_flush_all(void *arg)
+ {
+diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
+index 7410640..3bb4fc2 100644
+--- a/arch/x86/xen/Makefile
++++ b/arch/x86/xen/Makefile
+@@ -8,6 +8,7 @@ endif
+ # Make sure early boot has no stackprotector
+ nostackp := $(call cc-option, -fno-stack-protector)
+ CFLAGS_enlighten.o := $(nostackp)
++CFLAGS_mmu.o := $(nostackp)
+
+ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
+ time.o xen-asm.o xen-asm_$(BITS).o \
+@@ -16,3 +17,4 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
+ obj-$(CONFIG_SMP) += smp.o
+ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
+ obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o
++
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index eb33aaa..3839a0f 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -51,6 +51,7 @@
+ #include <asm/pgtable.h>
+ #include <asm/tlbflush.h>
+ #include <asm/reboot.h>
++#include <asm/stackprotector.h>
+
+ #include "xen-ops.h"
+ #include "mmu.h"
+@@ -330,18 +331,28 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
+ unsigned long frames[pages];
+ int f;
+
+- /* A GDT can be up to 64k in size, which corresponds to 8192
+- 8-byte entries, or 16 4k pages.. */
++ /*
++ * A GDT can be up to 64k in size, which corresponds to 8192
++ * 8-byte entries, or 16 4k pages..
++ */
+
+ BUG_ON(size > 65536);
+ BUG_ON(va & ~PAGE_MASK);
+
+ for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
+ int level;
+- pte_t *ptep = lookup_address(va, &level);
++ pte_t *ptep;
+ unsigned long pfn, mfn;
+ void *virt;
+
++ /*
++ * The GDT is per-cpu and is in the percpu data area.
++ * That can be virtually mapped, so we need to do a
++ * page-walk to get the underlying MFN for the
++ * hypercall. The page can also be in the kernel's
++ * linear range, so we need to RO that mapping too.
++ */
++ ptep = lookup_address(va, &level);
+ BUG_ON(ptep == NULL);
+
+ pfn = pte_pfn(*ptep);
+@@ -358,6 +369,44 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
+ BUG();
+ }
+
++/*
++ * load_gdt for early boot, when the gdt is only mapped once
++ */
++static __init void xen_load_gdt_boot(const struct desc_ptr *dtr)
++{
++ unsigned long va = dtr->address;
++ unsigned int size = dtr->size + 1;
++ unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
++ unsigned long frames[pages];
++ int f;
++
++ /*
++ * A GDT can be up to 64k in size, which corresponds to 8192
++ * 8-byte entries, or 16 4k pages..
++ */
++
++ BUG_ON(size > 65536);
++ BUG_ON(va & ~PAGE_MASK);
++
++ for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
++ pte_t pte;
++ unsigned long pfn, mfn;
++
++ pfn = virt_to_pfn(va);
++ mfn = pfn_to_mfn(pfn);
++
++ pte = pfn_pte(pfn, PAGE_KERNEL_RO);
++
++ if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0))
++ BUG();
++
++ frames[f] = mfn;
++ }
++
++ if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
++ BUG();
++}
++
+ static void load_TLS_descriptor(struct thread_struct *t,
+ unsigned int cpu, unsigned int i)
+ {
+@@ -581,6 +630,29 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
+ preempt_enable();
+ }
+
++/*
++ * Version of write_gdt_entry for use at early boot-time needed to
++ * update an entry as simply as possible.
++ */
++static __init void xen_write_gdt_entry_boot(struct desc_struct *dt, int entry,
++ const void *desc, int type)
++{
++ switch (type) {
++ case DESC_LDT:
++ case DESC_TSS:
++ /* ignore */
++ break;
++
++ default: {
++ xmaddr_t maddr = virt_to_machine(&dt[entry]);
++
++ if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc))
++ dt[entry] = *(struct desc_struct *)desc;
++ }
++
++ }
++}
++
+ static void xen_load_sp0(struct tss_struct *tss,
+ struct thread_struct *thread)
+ {
+@@ -965,6 +1037,23 @@ static const struct machine_ops __initdata xen_machine_ops = {
+ .emergency_restart = xen_emergency_restart,
+ };
+
++/*
++ * Set up the GDT and segment registers for -fstack-protector. Until
++ * we do this, we have to be careful not to call any stack-protected
++ * function, which is most of the kernel.
++ */
++static void __init xen_setup_stackprotector(void)
++{
++ pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot;
++ pv_cpu_ops.load_gdt = xen_load_gdt_boot;
++
++ setup_stack_canary_segment(0);
++ switch_to_new_gdt(0);
++
++ pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry;
++ pv_cpu_ops.load_gdt = xen_load_gdt;
++}
++
+ /* First C function to be called on Xen boot */
+ asmlinkage void __init xen_start_kernel(void)
+ {
+@@ -983,14 +1072,34 @@ asmlinkage void __init xen_start_kernel(void)
+ pv_apic_ops = xen_apic_ops;
+ pv_mmu_ops = xen_mmu_ops;
+
+-#ifdef CONFIG_X86_64
+ /*
+- * Setup percpu state. We only need to do this for 64-bit
+- * because 32-bit already has %fs set properly.
++ * Set up some pagetable state before starting to set any ptes.
+ */
+- load_percpu_segment(0);
++
++ /* Prevent unwanted bits from being set in PTEs. */
++ __supported_pte_mask &= ~_PAGE_GLOBAL;
++ if (!xen_initial_domain())
++ __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
++
++ __supported_pte_mask |= _PAGE_IOMAP;
++
++#ifdef CONFIG_X86_64
++ /* Work out if we support NX */
++ check_efer();
+ #endif
+
++ xen_setup_features();
++
++ /* Get mfn list */
++ if (!xen_feature(XENFEAT_auto_translated_physmap))
++ xen_build_dynamic_phys_to_machine();
++
++ /*
++ * Set up kernel GDT and segment registers, mainly so that
++ * -fstack-protector code can be executed.
++ */
++ xen_setup_stackprotector();
++
+ xen_init_irq_ops();
+ xen_init_cpuid_mask();
+
+@@ -1001,8 +1110,6 @@ asmlinkage void __init xen_start_kernel(void)
+ set_xen_basic_apic_ops();
+ #endif
+
+- xen_setup_features();
+-
+ if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
+ pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
+ pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
+@@ -1019,22 +1126,8 @@ asmlinkage void __init xen_start_kernel(void)
+
+ xen_smp_init();
+
+- /* Get mfn list */
+- if (!xen_feature(XENFEAT_auto_translated_physmap))
+- xen_build_dynamic_phys_to_machine();
+-
+ pgd = (pgd_t *)xen_start_info->pt_base;
+
+- /* Prevent unwanted bits from being set in PTEs. */
+- __supported_pte_mask &= ~_PAGE_GLOBAL;
+- if (!xen_initial_domain())
+- __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
+-
+-#ifdef CONFIG_X86_64
+- /* Work out if we support NX */
+- check_efer();
+-#endif
+-
+ /* Don't do the full vcpu_info placement stuff until we have a
+ possible map and a non-dummy shared_info. */
+ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
+diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
+index 429834e..fe03eee 100644
+--- a/arch/x86/xen/smp.c
++++ b/arch/x86/xen/smp.c
+@@ -236,6 +236,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
+ ctxt->user_regs.ss = __KERNEL_DS;
+ #ifdef CONFIG_X86_32
+ ctxt->user_regs.fs = __KERNEL_PERCPU;
++ ctxt->user_regs.gs = __KERNEL_STACK_CANARY;
+ #else
+ ctxt->gs_base_kernel = per_cpu_offset(cpu);
+ #endif
+diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
+index 5601506..36a5141 100644
+--- a/arch/x86/xen/spinlock.c
++++ b/arch/x86/xen/spinlock.c
+@@ -187,7 +187,6 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
+ struct xen_spinlock *prev;
+ int irq = __get_cpu_var(lock_kicker_irq);
+ int ret;
+- unsigned long flags;
+ u64 start;
+
+ /* If kicker interrupts not initialized yet, just spin */
+@@ -199,16 +198,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
+ /* announce we're spinning */
+ prev = spinning_lock(xl);
+
+- flags = __raw_local_save_flags();
+- if (irq_enable) {
+- ADD_STATS(taken_slow_irqenable, 1);
+- raw_local_irq_enable();
+- }
+-
+ ADD_STATS(taken_slow, 1);
+ ADD_STATS(taken_slow_nested, prev != NULL);
+
+ do {
++ unsigned long flags;
++
+ /* clear pending */
+ xen_clear_irq_pending(irq);
+
+@@ -228,6 +223,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
+ goto out;
+ }
+
++ flags = __raw_local_save_flags();
++ if (irq_enable) {
++ ADD_STATS(taken_slow_irqenable, 1);
++ raw_local_irq_enable();
++ }
++
+ /*
+ * Block until irq becomes pending. If we're
+ * interrupted at this point (after the trylock but
+@@ -238,13 +239,15 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
+ * pending.
+ */
+ xen_poll_irq(irq);
++
++ raw_local_irq_restore(flags);
++
+ ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq));
+ } while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */
+
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+
+ out:
+- raw_local_irq_restore(flags);
+ unspinning_lock(xl, prev);
+ spin_time_accum_blocked(start);
+
+@@ -323,8 +326,13 @@ static void xen_spin_unlock(struct raw_spinlock *lock)
+ smp_wmb(); /* make sure no writes get moved after unlock */
+ xl->lock = 0; /* release lock */
+
+- /* make sure unlock happens before kick */
+- barrier();
++ /*
++ * Make sure unlock happens before checking for waiting
++ * spinners. We need a strong barrier to enforce the
++ * write-read ordering to different memory locations, as the
++ * CPU makes no implied guarantees about their ordering.
++ */
++ mb();
+
+ if (unlikely(xl->spinners))
+ xen_spin_unlock_slow(xl);
+diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
+index 12158e0..da9d6d2 100644
+--- a/drivers/acpi/pci_slot.c
++++ b/drivers/acpi/pci_slot.c
+@@ -57,7 +57,7 @@ ACPI_MODULE_NAME("pci_slot");
+ MY_NAME , ## arg); \
+ } while (0)
+
+-#define SLOT_NAME_SIZE 20 /* Inspired by #define in acpiphp.h */
++#define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */
+
+ struct acpi_pci_slot {
+ acpi_handle root_handle; /* handle of the root bridge */
+@@ -149,7 +149,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
+ return AE_OK;
+ }
+
+- snprintf(name, sizeof(name), "%u", (u32)sun);
++ snprintf(name, sizeof(name), "%llu", sun);
+ pci_slot = pci_create_slot(pci_bus, device, name, NULL);
+ if (IS_ERR(pci_slot)) {
+ err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index fe3eba5..289c4f8 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -2861,8 +2861,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ if (ahci_asus_m2a_vm_32bit_only(pdev))
+ hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
+
+- if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
+- pci_enable_msi(pdev);
++ if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
++ pci_intx(pdev, 1);
+
+ /* save initial config */
+ ahci_save_initial_config(pdev, hpriv);
+diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
+index 33a74f1..567f3f7 100644
+--- a/drivers/ata/pata_amd.c
++++ b/drivers/ata/pata_amd.c
+@@ -307,6 +307,9 @@ static unsigned long nv_mode_filter(struct ata_device *dev,
+ limit |= ATA_MASK_PIO;
+ if (!(limit & (ATA_MASK_MWDMA | ATA_MASK_UDMA)))
+ limit |= ATA_MASK_MWDMA | ATA_MASK_UDMA;
++ /* PIO4, MWDMA2, UDMA2 should always be supported regardless of
++ cable detection result */
++ limit |= ata_pack_xfermask(ATA_PIO4, ATA_MWDMA2, ATA_UDMA2);
+
+ ata_port_printk(ap, KERN_DEBUG, "nv_mode_filter: 0x%lx&0x%lx->0x%lx, "
+ "BIOS=0x%lx (0x%x) ACPI=0x%lx%s\n",
+diff --git a/drivers/base/base.h b/drivers/base/base.h
+index b528145..1e52c12 100644
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -104,7 +104,7 @@ extern int system_bus_init(void);
+ extern int cpu_dev_init(void);
+
+ extern int bus_add_device(struct device *dev);
+-extern void bus_attach_device(struct device *dev);
++extern void bus_probe_device(struct device *dev);
+ extern void bus_remove_device(struct device *dev);
+
+ extern int bus_add_driver(struct device_driver *drv);
+diff --git a/drivers/base/bus.c b/drivers/base/bus.c
+index 4b04a15..973bf2a 100644
+--- a/drivers/base/bus.c
++++ b/drivers/base/bus.c
+@@ -459,8 +459,9 @@ static inline void remove_deprecated_bus_links(struct device *dev) { }
+ * bus_add_device - add device to bus
+ * @dev: device being added
+ *
++ * - Add device's bus attributes.
++ * - Create links to device's bus.
+ * - Add the device to its bus's list of devices.
+- * - Create link to device's bus.
+ */
+ int bus_add_device(struct device *dev)
+ {
+@@ -483,6 +484,7 @@ int bus_add_device(struct device *dev)
+ error = make_deprecated_bus_links(dev);
+ if (error)
+ goto out_deprecated;
++ klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
+ }
+ return 0;
+
+@@ -498,24 +500,19 @@ out_put:
+ }
+
+ /**
+- * bus_attach_device - add device to bus
+- * @dev: device tried to attach to a driver
++ * bus_probe_device - probe drivers for a new device
++ * @dev: device to probe
+ *
+- * - Add device to bus's list of devices.
+- * - Try to attach to driver.
++ * - Automatically probe for a driver if the bus allows it.
+ */
+-void bus_attach_device(struct device *dev)
++void bus_probe_device(struct device *dev)
+ {
+ struct bus_type *bus = dev->bus;
+- int ret = 0;
++ int ret;
+
+- if (bus) {
+- if (bus->p->drivers_autoprobe)
+- ret = device_attach(dev);
++ if (bus && bus->p->drivers_autoprobe) {
++ ret = device_attach(dev);
+ WARN_ON(ret < 0);
+- if (ret >= 0)
+- klist_add_tail(&dev->p->knode_bus,
+- &bus->p->klist_devices);
+ }
+ }
+
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 7ecb193..c34774d 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -945,7 +945,7 @@ int device_add(struct device *dev)
+ BUS_NOTIFY_ADD_DEVICE, dev);
+
+ kobject_uevent(&dev->kobj, KOBJ_ADD);
+- bus_attach_device(dev);
++ bus_probe_device(dev);
+ if (parent)
+ klist_add_tail(&dev->p->knode_parent,
+ &parent->p->klist_children);
+diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
+index dee0f1f..6cf88b6 100644
+--- a/drivers/char/agp/intel-agp.c
++++ b/drivers/char/agp/intel-agp.c
+@@ -679,23 +679,39 @@ static void intel_i830_setup_flush(void)
+ if (!intel_private.i8xx_page)
+ return;
+
+- /* make page uncached */
+- map_page_into_agp(intel_private.i8xx_page);
+-
+ intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page);
+ if (!intel_private.i8xx_flush_page)
+ intel_i830_fini_flush();
+ }
+
++static void
++do_wbinvd(void *null)
++{
++ wbinvd();
++}
++
++/* The chipset_flush interface needs to get data that has already been
++ * flushed out of the CPU all the way out to main memory, because the GPU
++ * doesn't snoop those buffers.
++ *
++ * The 8xx series doesn't have the same lovely interface for flushing the
++ * chipset write buffers that the later chips do. According to the 865
++ * specs, it's 64 octwords, or 1KB. So, to get those previous things in
++ * that buffer out, we just fill 1KB and clflush it out, on the assumption
++ * that it'll push whatever was in there out. It appears to work.
++ */
+ static void intel_i830_chipset_flush(struct agp_bridge_data *bridge)
+ {
+ unsigned int *pg = intel_private.i8xx_flush_page;
+- int i;
+
+- for (i = 0; i < 256; i += 2)
+- *(pg + i) = i;
++ memset(pg, 0, 1024);
+
+- wmb();
++ if (cpu_has_clflush) {
++ clflush_cache_range(pg, 1024);
++ } else {
++ if (on_each_cpu(do_wbinvd, NULL, 1) != 0)
++ printk(KERN_ERR "Timed out waiting for cache flush.\n");
++ }
+ }
+
+ /* The intel i830 automatically initializes the agp aperture during POST.
+diff --git a/drivers/char/pty.c b/drivers/char/pty.c
+index b33d668..53761ce 100644
+--- a/drivers/char/pty.c
++++ b/drivers/char/pty.c
+@@ -120,8 +120,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
+ /* Stuff the data into the input queue of the other end */
+ c = tty_insert_flip_string(to, buf, c);
+ /* And shovel */
+- tty_flip_buffer_push(to);
+- tty_wakeup(tty);
++ if (c) {
++ tty_flip_buffer_push(to);
++ tty_wakeup(tty);
++ }
+ }
+ return c;
+ }
+diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+index a3afa0c..9fc9517 100644
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -1184,6 +1184,7 @@ int tty_init_termios(struct tty_struct *tty)
+ tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(tty_init_termios);
+
+ /**
+ * tty_driver_install_tty() - install a tty entry in the driver
+diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
+index 9769b11..549bd0f 100644
+--- a/drivers/char/tty_port.c
++++ b/drivers/char/tty_port.c
+@@ -96,6 +96,14 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
+ }
+ EXPORT_SYMBOL(tty_port_tty_set);
+
++static void tty_port_shutdown(struct tty_port *port)
++{
++ if (port->ops->shutdown &&
++ test_and_clear_bit(ASYNC_INITIALIZED, &port->flags))
++ port->ops->shutdown(port);
++
++}
++
+ /**
+ * tty_port_hangup - hangup helper
+ * @port: tty port
+@@ -116,6 +124,7 @@ void tty_port_hangup(struct tty_port *port)
+ port->tty = NULL;
+ spin_unlock_irqrestore(&port->lock, flags);
+ wake_up_interruptible(&port->open_wait);
++ tty_port_shutdown(port);
+ }
+ EXPORT_SYMBOL(tty_port_hangup);
+
+@@ -296,15 +305,17 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
+
+ if (port->count) {
+ spin_unlock_irqrestore(&port->lock, flags);
++ if (port->ops->drop)
++ port->ops->drop(port);
+ return 0;
+ }
+- port->flags |= ASYNC_CLOSING;
++ set_bit(ASYNC_CLOSING, &port->flags);
+ tty->closing = 1;
+ spin_unlock_irqrestore(&port->lock, flags);
+ /* Don't block on a stalled port, just pull the chain */
+ if (tty->flow_stopped)
+ tty_driver_flush_buffer(tty);
+- if (port->flags & ASYNC_INITIALIZED &&
++ if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
+ port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, port->closing_wait);
+ if (port->drain_delay) {
+@@ -318,6 +329,9 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
+ timeout = 2 * HZ;
+ schedule_timeout_interruptible(timeout);
+ }
++ /* Don't call port->drop for the last reference. Callers will want
++ to drop the last active reference in ->shutdown() or the tty
++ shutdown path */
+ return 1;
+ }
+ EXPORT_SYMBOL(tty_port_close_start);
+@@ -348,3 +362,14 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
+ EXPORT_SYMBOL(tty_port_close_end);
++
++void tty_port_close(struct tty_port *port, struct tty_struct *tty,
++ struct file *filp)
++{
++ if (tty_port_close_start(port, tty, filp) == 0)
++ return;
++ tty_port_shutdown(port);
++ tty_port_close_end(port, tty);
++ tty_port_tty_set(port, NULL);
++}
++EXPORT_SYMBOL(tty_port_close);
+diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
+index fc4b68a..c078d99 100644
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -94,8 +94,6 @@ static int i915_resume(struct drm_device *dev)
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret = 0;
+
+- pci_set_power_state(dev->pdev, PCI_D0);
+- pci_restore_state(dev->pdev);
+ if (pci_enable_device(dev->pdev))
+ return -1;
+ pci_set_master(dev->pdev);
+diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
+index 80e5ba4..2b7aeee 100644
+--- a/drivers/gpu/drm/i915/i915_gem.c
++++ b/drivers/gpu/drm/i915/i915_gem.c
+@@ -1151,27 +1151,21 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ mutex_lock(&dev->struct_mutex);
+ if (!obj_priv->gtt_space) {
+ ret = i915_gem_object_bind_to_gtt(obj, obj_priv->gtt_alignment);
+- if (ret) {
+- mutex_unlock(&dev->struct_mutex);
+- return VM_FAULT_SIGBUS;
+- }
+-
+- ret = i915_gem_object_set_to_gtt_domain(obj, write);
+- if (ret) {
+- mutex_unlock(&dev->struct_mutex);
+- return VM_FAULT_SIGBUS;
+- }
++ if (ret)
++ goto unlock;
+
+ list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
++
++ ret = i915_gem_object_set_to_gtt_domain(obj, write);
++ if (ret)
++ goto unlock;
+ }
+
+ /* Need a new fence register? */
+ if (obj_priv->tiling_mode != I915_TILING_NONE) {
+ ret = i915_gem_object_get_fence_reg(obj);
+- if (ret) {
+- mutex_unlock(&dev->struct_mutex);
+- return VM_FAULT_SIGBUS;
+- }
++ if (ret)
++ goto unlock;
+ }
+
+ pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
+@@ -1179,18 +1173,18 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+
+ /* Finally, remap it using the new GTT offset */
+ ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
+-
++unlock:
+ mutex_unlock(&dev->struct_mutex);
+
+ switch (ret) {
++ case 0:
++ case -ERESTARTSYS:
++ return VM_FAULT_NOPAGE;
+ case -ENOMEM:
+ case -EAGAIN:
+ return VM_FAULT_OOM;
+- case -EFAULT:
+- case -EINVAL:
+- return VM_FAULT_SIGBUS;
+ default:
+- return VM_FAULT_NOPAGE;
++ return VM_FAULT_SIGBUS;
+ }
+ }
+
+@@ -2506,16 +2500,6 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
+ if (obj_priv->pages == NULL)
+ return;
+
+- /* XXX: The 865 in particular appears to be weird in how it handles
+- * cache flushing. We haven't figured it out, but the
+- * clflush+agp_chipset_flush doesn't appear to successfully get the
+- * data visible to the PGU, while wbinvd + agp_chipset_flush does.
+- */
+- if (IS_I865G(obj->dev)) {
+- wbinvd();
+- return;
+- }
+-
+ drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE);
+ }
+
+@@ -3007,6 +2991,16 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
+ return -EINVAL;
+ }
+
++ if (reloc->delta >= target_obj->size) {
++ DRM_ERROR("Relocation beyond target object bounds: "
++ "obj %p target %d delta %d size %d.\n",
++ obj, reloc->target_handle,
++ (int) reloc->delta, (int) target_obj->size);
++ drm_gem_object_unreference(target_obj);
++ i915_gem_object_unpin(obj);
++ return -EINVAL;
++ }
++
+ if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+ reloc->read_domains & I915_GEM_DOMAIN_CPU) {
+ DRM_ERROR("reloc with read/write CPU domains: "
+@@ -3837,7 +3831,8 @@ void i915_gem_free_object(struct drm_gem_object *obj)
+
+ i915_gem_object_unbind(obj);
+
+- i915_gem_free_mmap_offset(obj);
++ if (obj_priv->mmap_offset)
++ i915_gem_free_mmap_offset(obj);
+
+ kfree(obj_priv->page_cpu_valid);
+ kfree(obj_priv->bit_17);
+diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
+index a2d527b..e774a4a 100644
+--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
++++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
+@@ -234,7 +234,13 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
+ uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+ bool need_disable;
+
+- if (!IS_I9XX(dev)) {
++ if (IS_IGDNG(dev)) {
++ /* On IGDNG whatever DRAM config, GPU always do
++ * same swizzling setup.
++ */
++ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
++ swizzle_y = I915_BIT_6_SWIZZLE_9;
++ } else if (!IS_I9XX(dev)) {
+ /* As far as we know, the 865 doesn't have these bit 6
+ * swizzling issues.
+ */
+@@ -317,13 +323,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
+ }
+ }
+
+- /* FIXME: check with memory config on IGDNG */
+- if (IS_IGDNG(dev)) {
+- DRM_ERROR("disable tiling on IGDNG...\n");
+- swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+- swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+- }
+-
+ dev_priv->mm.bit_6_swizzle_x = swizzle_x;
+ dev_priv->mm.bit_6_swizzle_y = swizzle_y;
+ }
+diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
+index 2955083..106a1ae 100644
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -1733,6 +1733,7 @@
+ #define DISPPLANE_NO_LINE_DOUBLE 0
+ #define DISPPLANE_STEREO_POLARITY_FIRST 0
+ #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
++#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* IGDNG */
+ #define DISPPLANE_TILED (1<<10)
+ #define DSPAADDR 0x70184
+ #define DSPASTRIDE 0x70188
+@@ -1867,6 +1868,8 @@
+ #define PF_ENABLE (1<<31)
+ #define PFA_WIN_SZ 0x68074
+ #define PFB_WIN_SZ 0x68874
++#define PFA_WIN_POS 0x68070
++#define PFB_WIN_POS 0x68870
+
+ /* legacy palette */
+ #define LGC_PALETTE_A 0x4a000
+@@ -1913,6 +1916,9 @@
+ #define GTIIR 0x44018
+ #define GTIER 0x4401c
+
++#define DISP_ARB_CTL 0x45000
++#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
++
+ /* PCH */
+
+ /* south display engine interrupt */
+diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
+index f806fcc..698a0ed 100644
+--- a/drivers/gpu/drm/i915/intel_bios.c
++++ b/drivers/gpu/drm/i915/intel_bios.c
+@@ -217,6 +217,9 @@ parse_general_features(struct drm_i915_private *dev_priv,
+ if (IS_I85X(dev_priv->dev))
+ dev_priv->lvds_ssc_freq =
+ general->ssc_freq ? 66 : 48;
++ else if (IS_IGDNG(dev_priv->dev))
++ dev_priv->lvds_ssc_freq =
++ general->ssc_freq ? 100 : 120;
+ else
+ dev_priv->lvds_ssc_freq =
+ general->ssc_freq ? 100 : 96;
+diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
+index 590f81c..5ae4c1a 100644
+--- a/drivers/gpu/drm/i915/intel_crt.c
++++ b/drivers/gpu/drm/i915/intel_crt.c
+@@ -151,13 +151,10 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
+ {
+ struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+- u32 adpa, temp;
++ u32 adpa;
+ bool ret;
+
+- temp = adpa = I915_READ(PCH_ADPA);
+-
+- adpa &= ~ADPA_DAC_ENABLE;
+- I915_WRITE(PCH_ADPA, adpa);
++ adpa = I915_READ(PCH_ADPA);
+
+ adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+
+@@ -184,8 +181,6 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
+ else
+ ret = false;
+
+- /* restore origin register */
+- I915_WRITE(PCH_ADPA, temp);
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 748ed50..8b5af29 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -818,7 +818,7 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+ refclk, best_clock);
+
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+- if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
++ if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
+ LVDS_CLKB_POWER_UP)
+ clock.p2 = limit->p2.p2_fast;
+ else
+@@ -1008,6 +1008,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
+ dspcntr &= ~DISPPLANE_TILED;
+ }
+
++ if (IS_IGDNG(dev))
++ /* must disable */
++ dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
++
+ I915_WRITE(dspcntr_reg, dspcntr);
+
+ Start = obj_priv->gtt_offset;
+@@ -1154,6 +1158,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF;
+ int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1;
+ int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ;
++ int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS;
+ int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
+ int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
+ int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
+@@ -1205,6 +1210,19 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
+ }
+ }
+
++ /* Enable panel fitting for LVDS */
++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
++ temp = I915_READ(pf_ctl_reg);
++ I915_WRITE(pf_ctl_reg, temp | PF_ENABLE);
++
++ /* currently full aspect */
++ I915_WRITE(pf_win_pos, 0);
++
++ I915_WRITE(pf_win_size,
++ (dev_priv->panel_fixed_mode->hdisplay << 16) |
++ (dev_priv->panel_fixed_mode->vdisplay));
++ }
++
+ /* Enable CPU pipe */
+ temp = I915_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) == 0) {
+@@ -1858,7 +1876,14 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
+ {
+ long entries_required, wm_size;
+
+- entries_required = (clock_in_khz * pixel_size * latency_ns) / 1000000;
++ /*
++ * Note: we need to make sure we don't overflow for various clock &
++ * latency values.
++ * clocks go from a few thousand to several hundred thousand.
++ * latency is usually a few thousand
++ */
++ entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) /
++ 1000;
+ entries_required /= wm->cacheline_size;
+
+ DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required);
+@@ -2616,6 +2641,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
+
+ intel_wait_for_vblank(dev);
+
++ if (IS_IGDNG(dev)) {
++ /* enable address swizzle for tiling buffer */
++ temp = I915_READ(DISP_ARB_CTL);
++ I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING);
++ }
++
+ I915_WRITE(dspcntr_reg, dspcntr);
+
+ /* Flush the plane changes */
+diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
+index 8df02ef..b7d091b 100644
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -305,6 +305,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
+ goto out;
+ }
+
++ /* full screen scale for now */
++ if (IS_IGDNG(dev))
++ goto out;
++
+ /* 965+ wants fuzzy fitting */
+ if (IS_I965G(dev))
+ pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) |
+@@ -332,8 +336,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
+ * to register description and PRM.
+ * Change the value here to see the borders for debugging
+ */
+- I915_WRITE(BCLRPAT_A, 0);
+- I915_WRITE(BCLRPAT_B, 0);
++ if (!IS_IGDNG(dev)) {
++ I915_WRITE(BCLRPAT_A, 0);
++ I915_WRITE(BCLRPAT_B, 0);
++ }
+
+ switch (lvds_priv->fitting_mode) {
+ case DRM_MODE_SCALE_NO_SCALE:
+@@ -582,7 +588,6 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
+ * settings.
+ */
+
+- /* No panel fitting yet, fixme */
+ if (IS_IGDNG(dev))
+ return;
+
+diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
+index d3b74ba..66dc1a5 100644
+--- a/drivers/gpu/drm/i915/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/intel_sdvo.c
+@@ -114,6 +114,9 @@ struct intel_sdvo_priv {
+ /* DDC bus used by this SDVO output */
+ uint8_t ddc_bus;
+
++ /* Mac mini hack -- use the same DDC as the analog connector */
++ struct i2c_adapter *analog_ddc_bus;
++
+ int save_sdvo_mult;
+ u16 save_active_outputs;
+ struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
+@@ -1478,6 +1481,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
+ return (caps > 1);
+ }
+
++static struct drm_connector *
++intel_find_analog_connector(struct drm_device *dev)
++{
++ struct drm_connector *connector;
++ struct intel_output *intel_output;
++
++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
++ intel_output = to_intel_output(connector);
++ if (intel_output->type == INTEL_OUTPUT_ANALOG)
++ return connector;
++ }
++ return NULL;
++}
++
++static int
++intel_analog_is_connected(struct drm_device *dev)
++{
++ struct drm_connector *analog_connector;
++ analog_connector = intel_find_analog_connector(dev);
++
++ if (!analog_connector)
++ return false;
++
++ if (analog_connector->funcs->detect(analog_connector) ==
++ connector_status_disconnected)
++ return false;
++
++ return true;
++}
++
+ enum drm_connector_status
+ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
+ {
+@@ -1488,6 +1521,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
+
+ edid = drm_get_edid(&intel_output->base,
+ intel_output->ddc_bus);
++
++ /* when there is no edid and no monitor is connected with VGA
++ * port, try to use the CRT ddc to read the EDID for DVI-connector
++ */
++ if (edid == NULL &&
++ sdvo_priv->analog_ddc_bus &&
++ !intel_analog_is_connected(intel_output->base.dev))
++ edid = drm_get_edid(&intel_output->base,
++ sdvo_priv->analog_ddc_bus);
+ if (edid != NULL) {
+ /* Don't report the output as connected if it's a DVI-I
+ * connector with a non-digital EDID coming out.
+@@ -1540,31 +1582,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
+ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
+ {
+ struct intel_output *intel_output = to_intel_output(connector);
++ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
++ int num_modes;
+
+ /* set the bus switch and get the modes */
+- intel_ddc_get_modes(intel_output);
++ num_modes = intel_ddc_get_modes(intel_output);
+
+-#if 0
+- struct drm_device *dev = encoder->dev;
+- struct drm_i915_private *dev_priv = dev->dev_private;
+- /* Mac mini hack. On this device, I get DDC through the analog, which
+- * load-detects as disconnected. I fail to DDC through the SDVO DDC,
+- * but it does load-detect as connected. So, just steal the DDC bits
+- * from analog when we fail at finding it the right way.
++ /*
++ * Mac mini hack. On this device, the DVI-I connector shares one DDC
++ * link between analog and digital outputs. So, if the regular SDVO
++ * DDC fails, check to see if the analog output is disconnected, in
++ * which case we'll look there for the digital DDC data.
+ */
+- crt = xf86_config->output[0];
+- intel_output = crt->driver_private;
+- if (intel_output->type == I830_OUTPUT_ANALOG &&
+- crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
+- I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A");
+- edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus);
+- xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true);
+- }
+- if (edid_mon) {
+- xf86OutputSetEDID(output, edid_mon);
+- modes = xf86OutputGetEDIDModes(output);
++ if (num_modes == 0 &&
++ sdvo_priv->analog_ddc_bus &&
++ !intel_analog_is_connected(intel_output->base.dev)) {
++ struct i2c_adapter *digital_ddc_bus;
++
++ /* Switch to the analog ddc bus and try that
++ */
++ digital_ddc_bus = intel_output->ddc_bus;
++ intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
++
++ (void) intel_ddc_get_modes(intel_output);
++
++ intel_output->ddc_bus = digital_ddc_bus;
+ }
+-#endif
+ }
+
+ /**
+@@ -1748,6 +1791,8 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
+ intel_i2c_destroy(intel_output->i2c_bus);
+ if (intel_output->ddc_bus)
+ intel_i2c_destroy(intel_output->ddc_bus);
++ if (sdvo_priv->analog_ddc_bus)
++ intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
+
+ if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
+ drm_mode_destroy(connector->dev,
+@@ -2074,10 +2119,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
+ }
+
+ /* setup the DDC bus. */
+- if (output_device == SDVOB)
++ if (output_device == SDVOB) {
+ intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+- else
++ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
++ "SDVOB/VGA DDC BUS");
++ } else {
+ intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
++ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
++ "SDVOC/VGA DDC BUS");
++ }
+
+ if (intel_output->ddc_bus == NULL)
+ goto err_i2c;
+@@ -2143,6 +2193,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
+ return true;
+
+ err_i2c:
++ if (sdvo_priv->analog_ddc_bus != NULL)
++ intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
+ if (intel_output->ddc_bus != NULL)
+ intel_i2c_destroy(intel_output->ddc_bus);
+ if (intel_output->i2c_bus != NULL)
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 5eb10c2..047844d 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1319,7 +1319,6 @@ static const struct hid_device_id hid_blacklist[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
+
+- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
+ { }
+ };
+diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
+index 8ff7e35..f33ac27 100644
+--- a/drivers/isdn/gigaset/interface.c
++++ b/drivers/isdn/gigaset/interface.c
+@@ -408,33 +408,28 @@ static int if_write_room(struct tty_struct *tty)
+ return retval;
+ }
+
+-/* FIXME: This function does not have error returns */
+-
+ static int if_chars_in_buffer(struct tty_struct *tty)
+ {
+ struct cardstate *cs;
+- int retval = -ENODEV;
++ int retval = 0;
+
+ cs = (struct cardstate *) tty->driver_data;
+ if (!cs) {
+ pr_err("%s: no cardstate\n", __func__);
+- return -ENODEV;
++ return 0;
+ }
+
+ gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
+
+- if (mutex_lock_interruptible(&cs->mutex))
+- return -ERESTARTSYS; // FIXME -EINTR?
++ mutex_lock(&cs->mutex);
+
+- if (!cs->connected) {
++ if (!cs->connected)
+ gig_dbg(DEBUG_IF, "not connected");
+- retval = -ENODEV;
+- } else if (!cs->open_count)
++ else if (!cs->open_count)
+ dev_warn(cs->dev, "%s: device not opened\n", __func__);
+- else if (cs->mstate != MS_LOCKED) {
++ else if (cs->mstate != MS_LOCKED)
+ dev_warn(cs->dev, "can't write to unlocked device\n");
+- retval = -EBUSY;
+- } else
++ else
+ retval = cs->ops->chars_in_buffer(cs);
+
+ mutex_unlock(&cs->mutex);
+diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
+index 1c2e544..ffe9306 100644
+--- a/drivers/media/video/em28xx/em28xx-cards.c
++++ b/drivers/media/video/em28xx/em28xx-cards.c
+@@ -2170,8 +2170,6 @@ static int em28xx_hint_board(struct em28xx *dev)
+ /* ----------------------------------------------------------------------- */
+ void em28xx_register_i2c_ir(struct em28xx *dev)
+ {
+- struct i2c_board_info info;
+- struct IR_i2c_init_data init_data;
+ const unsigned short addr_list[] = {
+ 0x30, 0x47, I2C_CLIENT_END
+ };
+@@ -2179,9 +2177,9 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
+ if (disable_ir)
+ return;
+
+- memset(&info, 0, sizeof(struct i2c_board_info));
+- memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
++ memset(&dev->info, 0, sizeof(&dev->info));
++ memset(&dev->init_data, 0, sizeof(dev->init_data));
++ strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
+
+ /* detect & configure */
+ switch (dev->model) {
+@@ -2191,19 +2189,19 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
+ break;
+ case (EM2800_BOARD_TERRATEC_CINERGY_200):
+ case (EM2820_BOARD_TERRATEC_CINERGY_250):
+- init_data.ir_codes = ir_codes_em_terratec;
+- init_data.get_key = em28xx_get_key_terratec;
+- init_data.name = "i2c IR (EM28XX Terratec)";
++ dev->init_data.ir_codes = ir_codes_em_terratec;
++ dev->init_data.get_key = em28xx_get_key_terratec;
++ dev->init_data.name = "i2c IR (EM28XX Terratec)";
+ break;
+ case (EM2820_BOARD_PINNACLE_USB_2):
+- init_data.ir_codes = ir_codes_pinnacle_grey;
+- init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
+- init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
++ dev->init_data.ir_codes = ir_codes_pinnacle_grey;
++ dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
++ dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
+ break;
+ case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
+- init_data.ir_codes = ir_codes_hauppauge_new;
+- init_data.get_key = em28xx_get_key_em_haup;
+- init_data.name = "i2c IR (EM2840 Hauppauge)";
++ dev->init_data.ir_codes = ir_codes_hauppauge_new;
++ dev->init_data.get_key = em28xx_get_key_em_haup;
++ dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
+ break;
+ case (EM2820_BOARD_MSI_VOX_USB_2):
+ break;
+@@ -2215,9 +2213,9 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
+ break;
+ }
+
+- if (init_data.name)
+- info.platform_data = &init_data;
+- i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
++ if (dev->init_data.name)
++ dev->info.platform_data = &dev->init_data;
++ i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
+ }
+
+ void em28xx_card_setup(struct em28xx *dev)
+diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
+index a2add61..cb2a70a 100644
+--- a/drivers/media/video/em28xx/em28xx.h
++++ b/drivers/media/video/em28xx/em28xx.h
+@@ -595,6 +595,10 @@ struct em28xx {
+ struct delayed_work sbutton_query_work;
+
+ struct em28xx_dvb *dvb;
++
++ /* I2C keyboard data */
++ struct i2c_board_info info;
++ struct IR_i2c_init_data init_data;
+ };
+
+ struct em28xx_ops {
+diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
+index 6e219c2..69e48ce 100644
+--- a/drivers/media/video/saa7134/saa7134-input.c
++++ b/drivers/media/video/saa7134/saa7134-input.c
+@@ -684,8 +684,6 @@ void saa7134_input_fini(struct saa7134_dev *dev)
+
+ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ {
+- struct i2c_board_info info;
+- struct IR_i2c_init_data init_data;
+ const unsigned short addr_list[] = {
+ 0x7a, 0x47, 0x71, 0x2d,
+ I2C_CLIENT_END
+@@ -705,32 +703,32 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ return;
+ }
+
+- memset(&info, 0, sizeof(struct i2c_board_info));
+- memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
++ memset(&dev->info, 0, sizeof(dev->info));
++ memset(&dev->init_data, 0, sizeof(dev->init_data));
++ strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
+
+ switch (dev->board) {
+ case SAA7134_BOARD_PINNACLE_PCTV_110i:
+ case SAA7134_BOARD_PINNACLE_PCTV_310i:
+- init_data.name = "Pinnacle PCTV";
++ dev->init_data.name = "Pinnacle PCTV";
+ if (pinnacle_remote == 0) {
+- init_data.get_key = get_key_pinnacle_color;
+- init_data.ir_codes = ir_codes_pinnacle_color;
++ dev->init_data.get_key = get_key_pinnacle_color;
++ dev->init_data.ir_codes = ir_codes_pinnacle_color;
+ } else {
+- init_data.get_key = get_key_pinnacle_grey;
+- init_data.ir_codes = ir_codes_pinnacle_grey;
++ dev->init_data.get_key = get_key_pinnacle_grey;
++ dev->init_data.ir_codes = ir_codes_pinnacle_grey;
+ }
+ break;
+ case SAA7134_BOARD_UPMOST_PURPLE_TV:
+- init_data.name = "Purple TV";
+- init_data.get_key = get_key_purpletv;
+- init_data.ir_codes = ir_codes_purpletv;
++ dev->init_data.name = "Purple TV";
++ dev->init_data.get_key = get_key_purpletv;
++ dev->init_data.ir_codes = ir_codes_purpletv;
+ break;
+ case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
+- init_data.name = "MSI TV at nywhere Plus";
+- init_data.get_key = get_key_msi_tvanywhere_plus;
+- init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
+- info.addr = 0x30;
++ dev->init_data.name = "MSI TV at nywhere Plus";
++ dev->init_data.get_key = get_key_msi_tvanywhere_plus;
++ dev->init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
++ dev->info.addr = 0x30;
+ /* MSI TV at nywhere Plus controller doesn't seem to
+ respond to probes unless we read something from
+ an existing device. Weird...
+@@ -741,9 +739,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ (1 == rc) ? "yes" : "no");
+ break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110:
+- init_data.name = "HVR 1110";
+- init_data.get_key = get_key_hvr1110;
+- init_data.ir_codes = ir_codes_hauppauge_new;
++ dev->init_data.name = "HVR 1110";
++ dev->init_data.get_key = get_key_hvr1110;
++ dev->init_data.ir_codes = ir_codes_hauppauge_new;
+ break;
+ case SAA7134_BOARD_BEHOLD_607FM_MK3:
+ case SAA7134_BOARD_BEHOLD_607FM_MK5:
+@@ -757,26 +755,26 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
+ case SAA7134_BOARD_BEHOLD_M63:
+ case SAA7134_BOARD_BEHOLD_M6_EXTRA:
+ case SAA7134_BOARD_BEHOLD_H6:
+- init_data.name = "BeholdTV";
+- init_data.get_key = get_key_beholdm6xx;
+- init_data.ir_codes = ir_codes_behold;
++ dev->init_data.name = "BeholdTV";
++ dev->init_data.get_key = get_key_beholdm6xx;
++ dev->init_data.ir_codes = ir_codes_behold;
+ break;
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+- info.addr = 0x40;
++ dev->info.addr = 0x40;
+ break;
+ }
+
+- if (init_data.name)
+- info.platform_data = &init_data;
++ if (dev->init_data.name)
++ dev->info.platform_data = &dev->init_data;
+ /* No need to probe if address is known */
+- if (info.addr) {
+- i2c_new_device(&dev->i2c_adap, &info);
++ if (dev->info.addr) {
++ i2c_new_device(&dev->i2c_adap, &dev->info);
+ return;
+ }
+
+ /* Address not known, fallback to probing */
+- i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
++ i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
+ }
+
+ static int saa7134_rc5_irq(struct saa7134_dev *dev)
+diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
+index fb564f1..4d85f5c 100644
+--- a/drivers/media/video/saa7134/saa7134.h
++++ b/drivers/media/video/saa7134/saa7134.h
+@@ -584,6 +584,10 @@ struct saa7134_dev {
+ int nosignal;
+ unsigned int insuspend;
+
++ /* I2C keyboard data */
++ struct i2c_board_info info;
++ struct IR_i2c_init_data init_data;
++
+ /* SAA7134_MPEG_* */
+ struct saa7134_ts ts;
+ struct saa7134_dmaqueue ts_q;
+diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
+index 5d0ba4f..9ad7bb4 100644
+--- a/drivers/message/fusion/mptbase.c
++++ b/drivers/message/fusion/mptbase.c
+@@ -1015,9 +1015,9 @@ mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
+ {
+ SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
+ pSge->Address.Low = cpu_to_le32
+- (lower_32_bits((unsigned long)(dma_addr)));
++ (lower_32_bits(dma_addr));
+ pSge->Address.High = cpu_to_le32
+- (upper_32_bits((unsigned long)dma_addr));
++ (upper_32_bits(dma_addr));
+ pSge->FlagsLength = cpu_to_le32
+ ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
+ }
+@@ -1038,8 +1038,8 @@ mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
+ u32 tmp;
+
+ pSge->Address.Low = cpu_to_le32
+- (lower_32_bits((unsigned long)(dma_addr)));
+- tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
++ (lower_32_bits(dma_addr));
++ tmp = (u32)(upper_32_bits(dma_addr));
+
+ /*
+ * 1078 errata workaround for the 36GB limitation
+@@ -1101,7 +1101,7 @@ mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
+ pChain->NextChainOffset = next;
+
+ pChain->Address.Low = cpu_to_le32(tmp);
+- tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
++ tmp = (u32)(upper_32_bits(dma_addr));
+ pChain->Address.High = cpu_to_le32(tmp);
+ }
+
+diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
+index 13e7d7b..dd8b6b3 100644
+--- a/drivers/mfd/ab3100-core.c
++++ b/drivers/mfd/ab3100-core.c
+@@ -643,7 +643,7 @@ struct ab3100_init_setting {
+ u8 setting;
+ };
+
+-static const struct ab3100_init_setting __initdata
++static const struct ab3100_init_setting __initconst
+ ab3100_init_settings[] = {
+ {
+ .abreg = AB3100_MCA,
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index 06084db..72f2df1 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -180,11 +180,11 @@ static int mmc_read_ext_csd(struct mmc_card *card)
+
+ err = mmc_send_ext_csd(card, ext_csd);
+ if (err) {
+- /*
+- * We all hosts that cannot perform the command
+- * to fail more gracefully
+- */
+- if (err != -EINVAL)
++ /* If the host or the card can't do the switch,
++ * fail more gracefully. */
++ if ((err != -EINVAL)
++ && (err != -ENOSYS)
++ && (err != -EFAULT))
+ goto out;
+
+ /*
+diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
+index cd81c39..65c32bf 100644
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -210,11 +210,11 @@ static int mmc_read_switch(struct mmc_card *card)
+
+ err = mmc_sd_switch(card, 0, 0, 1, status);
+ if (err) {
+- /*
+- * We all hosts that cannot perform the command
+- * to fail more gracefully
+- */
+- if (err != -EINVAL)
++ /* If the host or the card can't do the switch,
++ * fail more gracefully. */
++ if ((err != -EINVAL)
++ && (err != -ENOSYS)
++ && (err != -EFAULT))
+ goto out;
+
+ printk(KERN_WARNING "%s: problem reading switch "
+diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
+index 61ea833..94bb61e 100644
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -282,16 +282,6 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
+ }
+ }
+
+-static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param)
+-{
+- struct map_info *map = mtd->priv;
+- struct cfi_private *cfi = map->fldrv_priv;
+- if (cfi->cfiq->BufWriteTimeoutTyp) {
+- pr_warning("Don't use write buffer on ST flash M29W128G\n");
+- cfi->cfiq->BufWriteTimeoutTyp = 0;
+- }
+-}
+-
+ static struct cfi_fixup cfi_fixup_table[] = {
+ { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
+ #ifdef AMD_BOOTLOC_BUG
+@@ -308,7 +298,6 @@ static struct cfi_fixup cfi_fixup_table[] = {
+ { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
+ { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
+ { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
+- { CFI_MFR_ST, 0x227E, fixup_M29W128G_write_buffer, NULL, },
+ #if !FORCE_WORD_WRITE
+ { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
+ #endif
+diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
+index 34d40e2..c5a84fd 100644
+--- a/drivers/mtd/chips/cfi_util.c
++++ b/drivers/mtd/chips/cfi_util.c
+@@ -81,6 +81,10 @@ void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
+ {
+ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
++ /* M29W128G flashes require an additional reset command
++ when exit qry mode */
++ if ((cfi->mfr == CFI_MFR_ST) && (cfi->id == 0x227E || cfi->id == 0x7E))
++ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+ }
+ EXPORT_SYMBOL_GPL(cfi_qry_mode_off);
+
+diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
+index 89bf85a..40b5658 100644
+--- a/drivers/mtd/nand/ndfc.c
++++ b/drivers/mtd/nand/ndfc.c
+@@ -102,8 +102,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,
+ wmb();
+ ecc = in_be32(ndfc->ndfcbase + NDFC_ECC);
+ /* The NDFC uses Smart Media (SMC) bytes order */
+- ecc_code[0] = p[2];
+- ecc_code[1] = p[1];
++ ecc_code[0] = p[1];
++ ecc_code[1] = p[2];
+ ecc_code[2] = p[3];
+
+ return 0;
+diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
+index 3e164f0..62d6a78 100644
+--- a/drivers/mtd/ofpart.c
++++ b/drivers/mtd/ofpart.c
+@@ -46,21 +46,12 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
+ const u32 *reg;
+ int len;
+
+- /* check if this is a partition node */
+- partname = of_get_property(pp, "name", &len);
+- if (strcmp(partname, "partition") != 0) {
++ reg = of_get_property(pp, "reg", &len);
++ if (!reg) {
+ nr_parts--;
+ continue;
+ }
+
+- reg = of_get_property(pp, "reg", &len);
+- if (!reg || (len != 2 * sizeof(u32))) {
+- of_node_put(pp);
+- dev_err(dev, "Invalid 'reg' on %s\n", node->full_name);
+- kfree(*pparts);
+- *pparts = NULL;
+- return -EINVAL;
+- }
+ (*pparts)[i].offset = reg[0];
+ (*pparts)[i].size = reg[1];
+
+@@ -75,6 +66,14 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
+ i++;
+ }
+
++ if (!i) {
++ of_node_put(pp);
++ dev_err(dev, "No valid partition found on %s\n", node->full_name);
++ kfree(*pparts);
++ *pparts = NULL;
++ return -EINVAL;
++ }
++
+ return nr_parts;
+ }
+ EXPORT_SYMBOL(of_mtd_parse_partitions);
+diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
+index a10c1d7..460bb88 100644
+--- a/drivers/net/can/vcan.c
++++ b/drivers/net/can/vcan.c
+@@ -80,7 +80,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
+ skb->dev = dev;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+- netif_rx(skb);
++ netif_rx_ni(skb);
+ }
+
+ static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
+diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
+index 1f9ec29..65a43c8 100644
+--- a/drivers/net/usb/kaweth.c
++++ b/drivers/net/usb/kaweth.c
+@@ -263,6 +263,7 @@ static int kaweth_control(struct kaweth_device *kaweth,
+ int timeout)
+ {
+ struct usb_ctrlrequest *dr;
++ int retval;
+
+ dbg("kaweth_control()");
+
+@@ -278,18 +279,21 @@ static int kaweth_control(struct kaweth_device *kaweth,
+ return -ENOMEM;
+ }
+
+- dr->bRequestType= requesttype;
++ dr->bRequestType = requesttype;
+ dr->bRequest = request;
+ dr->wValue = cpu_to_le16(value);
+ dr->wIndex = cpu_to_le16(index);
+ dr->wLength = cpu_to_le16(size);
+
+- return kaweth_internal_control_msg(kaweth->dev,
+- pipe,
+- dr,
+- data,
+- size,
+- timeout);
++ retval = kaweth_internal_control_msg(kaweth->dev,
++ pipe,
++ dr,
++ data,
++ size,
++ timeout);
++
++ kfree(dr);
++ return retval;
+ }
+
+ /****************************************************************
+diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
+index 007eb85..1084ca6 100644
+--- a/drivers/net/wireless/ath/ar9170/usb.c
++++ b/drivers/net/wireless/ath/ar9170/usb.c
+@@ -64,6 +64,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
+ { USB_DEVICE(0x0cf3, 0x9170) },
+ /* Atheros TG121N */
+ { USB_DEVICE(0x0cf3, 0x1001) },
++ /* TP-Link TL-WN821N v2 */
++ { USB_DEVICE(0x0cf3, 0x1002) },
+ /* Cace Airpcap NX */
+ { USB_DEVICE(0xcace, 0x0300) },
+ /* D-Link DWA 160A */
+diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
+index 6358233..778baf7 100644
+--- a/drivers/net/wireless/ath/ath5k/ath5k.h
++++ b/drivers/net/wireless/ath/ath5k/ath5k.h
+@@ -1164,6 +1164,7 @@ extern void ath5k_unregister_leds(struct ath5k_softc *sc);
+
+ /* Reset Functions */
+ extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
++extern int ath5k_hw_on_hold(struct ath5k_hw *ah);
+ extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
+ /* Power management functions */
+ extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
+diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
+index c41ef58..605b8f6 100644
+--- a/drivers/net/wireless/ath/ath5k/attach.c
++++ b/drivers/net/wireless/ath/ath5k/attach.c
+@@ -145,7 +145,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
+ goto err_free;
+
+ /* Bring device out of sleep and reset it's units */
+- ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
++ ret = ath5k_hw_nic_wakeup(ah, 0, true);
+ if (ret)
+ goto err_free;
+
+diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
+index ba6d225..753f50e 100644
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -666,7 +666,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+
+ ath5k_led_off(sc);
+
+- free_irq(pdev->irq, sc);
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+@@ -694,18 +693,8 @@ ath5k_pci_resume(struct pci_dev *pdev)
+ */
+ 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");
+- goto err_no_irq;
+- }
+-
+ ath5k_led_enable(sc);
+ return 0;
+-
+-err_no_irq:
+- pci_disable_device(pdev);
+- return err;
+ }
+ #endif /* CONFIG_PM */
+
+@@ -2445,27 +2434,29 @@ ath5k_stop_hw(struct ath5k_softc *sc)
+ ret = ath5k_stop_locked(sc);
+ if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
+ /*
+- * Set the chip in full sleep mode. Note that we are
+- * careful to do this only when bringing the interface
+- * completely to a stop. When the chip is in this state
+- * it must be carefully woken up or references to
+- * registers in the PCI clock domain may freeze the bus
+- * (and system). This varies by chip and is mostly an
+- * issue with newer parts that go to sleep more quickly.
+- */
+- if (sc->ah->ah_mac_srev >= 0x78) {
+- /*
+- * XXX
+- * don't put newer MAC revisions > 7.8 to sleep because
+- * of the above mentioned problems
+- */
+- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
+- "not putting device to sleep\n");
+- } else {
+- ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+- "putting device to full sleep\n");
+- ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
+- }
++ * Don't set the card in full sleep mode!
++ *
++ * a) When the device is in this state it must be carefully
++ * woken up or references to registers in the PCI clock
++ * domain may freeze the bus (and system). This varies
++ * by chip and is mostly an issue with newer parts
++ * (madwifi sources mentioned srev >= 0x78) that go to
++ * sleep more quickly.
++ *
++ * b) On older chips full sleep results a weird behaviour
++ * during wakeup. I tested various cards with srev < 0x78
++ * and they don't wake up after module reload, a second
++ * module reload is needed to bring the card up again.
++ *
++ * Until we figure out what's going on don't enable
++ * full chip reset on any chip (this is what Legacy HAL
++ * and Sam's HAL do anyway). Instead Perform a full reset
++ * on the device (same as initial state after attach) and
++ * leave it idle (keep MAC/BB on warm reset) */
++ ret = ath5k_hw_on_hold(sc->ah);
++
++ ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
++ "putting device to sleep\n");
+ }
+ ath5k_txbuf_free(sc, sc->bbuf);
+
+diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
+index bd0a97a..4980621 100644
+--- a/drivers/net/wireless/ath/ath5k/reset.c
++++ b/drivers/net/wireless/ath/ath5k/reset.c
+@@ -258,29 +258,35 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
+ if (!set_chip)
+ goto commit;
+
+- /* Preserve sleep duration */
+ data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
++
++ /* If card is down we 'll get 0xffff... so we
++ * need to clean this up before we write the register
++ */
+ if (data & 0xffc00000)
+ data = 0;
+ else
+- data = data & 0xfffcffff;
++ /* Preserve sleep duration etc */
++ data = data & ~AR5K_SLEEP_CTL_SLE;
+
+- ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
++ ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
++ AR5K_SLEEP_CTL);
+ udelay(15);
+
+- for (i = 50; i > 0; i--) {
++ for (i = 200; i > 0; i--) {
+ /* Check if the chip did wake up */
+ if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+ AR5K_PCICFG_SPWR_DN) == 0)
+ break;
+
+ /* Wait a bit and retry */
+- udelay(200);
+- ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
++ udelay(50);
++ ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
++ AR5K_SLEEP_CTL);
+ }
+
+ /* Fail if the chip didn't wake up */
+- if (i <= 0)
++ if (i == 0)
+ return -EIO;
+
+ break;
+@@ -297,6 +303,64 @@ commit:
+ }
+
+ /*
++ * Put device on hold
++ *
++ * Put MAC and Baseband on warm reset and
++ * keep that state (don't clean sleep control
++ * register). After this MAC and Baseband are
++ * disabled and a full reset is needed to come
++ * back. This way we save as much power as possible
++ * without puting the card on full sleep.
++ */
++int ath5k_hw_on_hold(struct ath5k_hw *ah)
++{
++ struct pci_dev *pdev = ah->ah_sc->pdev;
++ u32 bus_flags;
++ int ret;
++
++ /* Make sure device is awake */
++ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
++ if (ret) {
++ ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
++ return ret;
++ }
++
++ /*
++ * Put chipset on warm reset...
++ *
++ * Note: puting PCI core on warm reset on PCI-E cards
++ * results card to hang and always return 0xffff... so
++ * we ingore that flag for PCI-E cards. On PCI cards
++ * this flag gets cleared after 64 PCI clocks.
++ */
++ bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
++
++ if (ah->ah_version == AR5K_AR5210) {
++ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
++ AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
++ AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
++ mdelay(2);
++ } else {
++ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
++ AR5K_RESET_CTL_BASEBAND | bus_flags);
++ }
++
++ if (ret) {
++ ATH5K_ERR(ah->ah_sc, "failed to put device on warm reset\n");
++ return -EIO;
++ }
++
++ /* ...wakeup again!*/
++ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
++ if (ret) {
++ ATH5K_ERR(ah->ah_sc, "failed to put device on hold\n");
++ return ret;
++ }
++
++ return ret;
++}
++
++/*
+ * Bring up MAC + PHY Chips and program PLL
+ * TODO: Half/Quarter rate support
+ */
+@@ -319,6 +383,50 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
+ return ret;
+ }
+
++ /*
++ * Put chipset on warm reset...
++ *
++ * Note: puting PCI core on warm reset on PCI-E cards
++ * results card to hang and always return 0xffff... so
++ * we ingore that flag for PCI-E cards. On PCI cards
++ * this flag gets cleared after 64 PCI clocks.
++ */
++ bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
++
++ if (ah->ah_version == AR5K_AR5210) {
++ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
++ AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
++ AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
++ mdelay(2);
++ } else {
++ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
++ AR5K_RESET_CTL_BASEBAND | bus_flags);
++ }
++
++ if (ret) {
++ ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
++ return -EIO;
++ }
++
++ /* ...wakeup again!...*/
++ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
++ if (ret) {
++ ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
++ return ret;
++ }
++
++ /* ...clear reset control register and pull device out of
++ * warm reset */
++ if (ath5k_hw_nic_reset(ah, 0)) {
++ ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
++ return -EIO;
++ }
++
++ /* On initialization skip PLL programming since we don't have
++ * a channel / mode set yet */
++ if (initial)
++ return 0;
++
+ if (ah->ah_version != AR5K_AR5210) {
+ /*
+ * Get channel mode flags
+@@ -384,39 +492,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
+ AR5K_PHY_TURBO);
+ }
+
+- /* reseting PCI on PCI-E cards results card to hang
+- * and always return 0xffff... so we ingore that flag
+- * for PCI-E cards */
+- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+-
+- /* Reset chipset */
+- if (ah->ah_version == AR5K_AR5210) {
+- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+- AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+- AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+- mdelay(2);
+- } else {
+- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+- AR5K_RESET_CTL_BASEBAND | bus_flags);
+- }
+- if (ret) {
+- ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
+- return -EIO;
+- }
+-
+- /* ...wakeup again!*/
+- ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+- if (ret) {
+- ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
+- return ret;
+- }
+-
+- /* ...final warm reset */
+- if (ath5k_hw_nic_reset(ah, 0)) {
+- ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
+- return -EIO;
+- }
+-
+ if (ah->ah_version != AR5K_AR5210) {
+
+ /* ...update PLL if needed */
+diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
+index 7da52f1..d83d430 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
+@@ -46,7 +46,7 @@
+ #include "iwl-5000-hw.h"
+
+ /* Highest firmware API version supported */
+-#define IWL1000_UCODE_API_MAX 2
++#define IWL1000_UCODE_API_MAX 3
+
+ /* Lowest firmware API version supported */
+ #define IWL1000_UCODE_API_MIN 1
+@@ -62,12 +62,14 @@ struct iwl_cfg iwl1000_bgn_cfg = {
+ .ucode_api_min = IWL1000_UCODE_API_MIN,
+ .sku = IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+- .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
++ .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
++ .max_ll_items = OTP_MAX_LL_ITEMS_1000,
++ .shadow_ram_support = false,
+ };
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
+index 46288e7..b73ab6c 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
++++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
+@@ -2784,11 +2784,50 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
+ return 0;
+ }
+
++#define IWL3945_UCODE_GET(item) \
++static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
++ u32 api_ver) \
++{ \
++ return le32_to_cpu(ucode->u.v1.item); \
++}
++
++static u32 iwl3945_ucode_get_header_size(u32 api_ver)
++{
++ return UCODE_HEADER_SIZE(1);
++}
++static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
++ u32 api_ver)
++{
++ return 0;
++}
++static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
++ u32 api_ver)
++{
++ return (u8 *) ucode->u.v1.data;
++}
++
++IWL3945_UCODE_GET(inst_size);
++IWL3945_UCODE_GET(data_size);
++IWL3945_UCODE_GET(init_size);
++IWL3945_UCODE_GET(init_data_size);
++IWL3945_UCODE_GET(boot_size);
++
+ static struct iwl_hcmd_ops iwl3945_hcmd = {
+ .rxon_assoc = iwl3945_send_rxon_assoc,
+ .commit_rxon = iwl3945_commit_rxon,
+ };
+
++static struct iwl_ucode_ops iwl3945_ucode = {
++ .get_header_size = iwl3945_ucode_get_header_size,
++ .get_build = iwl3945_ucode_get_build,
++ .get_inst_size = iwl3945_ucode_get_inst_size,
++ .get_data_size = iwl3945_ucode_get_data_size,
++ .get_init_size = iwl3945_ucode_get_init_size,
++ .get_init_data_size = iwl3945_ucode_get_init_data_size,
++ .get_boot_size = iwl3945_ucode_get_boot_size,
++ .get_data = iwl3945_ucode_get_data,
++};
++
+ static struct iwl_lib_ops iwl3945_lib = {
+ .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl3945_hw_txq_free_tfd,
+@@ -2829,6 +2868,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
+ };
+
+ static struct iwl_ops iwl3945_ops = {
++ .ucode = &iwl3945_ucode,
+ .lib = &iwl3945_lib,
+ .hcmd = &iwl3945_hcmd,
+ .utils = &iwl3945_hcmd_utils,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
+index 8f3d4bc..157ee15 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
+@@ -2221,12 +2221,50 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
+ cancel_work_sync(&priv->txpower_work);
+ }
+
++#define IWL4965_UCODE_GET(item) \
++static u32 iwl4965_ucode_get_##item(const struct iwl_ucode_header *ucode,\
++ u32 api_ver) \
++{ \
++ return le32_to_cpu(ucode->u.v1.item); \
++}
++
++static u32 iwl4965_ucode_get_header_size(u32 api_ver)
++{
++ return UCODE_HEADER_SIZE(1);
++}
++static u32 iwl4965_ucode_get_build(const struct iwl_ucode_header *ucode,
++ u32 api_ver)
++{
++ return 0;
++}
++static u8 *iwl4965_ucode_get_data(const struct iwl_ucode_header *ucode,
++ u32 api_ver)
++{
++ return (u8 *) ucode->u.v1.data;
++}
++
++IWL4965_UCODE_GET(inst_size);
++IWL4965_UCODE_GET(data_size);
++IWL4965_UCODE_GET(init_size);
++IWL4965_UCODE_GET(init_data_size);
++IWL4965_UCODE_GET(boot_size);
++
+ static struct iwl_hcmd_ops iwl4965_hcmd = {
+ .rxon_assoc = iwl4965_send_rxon_assoc,
+ .commit_rxon = iwl_commit_rxon,
+ .set_rxon_chain = iwl_set_rxon_chain,
+ };
+
++static struct iwl_ucode_ops iwl4965_ucode = {
++ .get_header_size = iwl4965_ucode_get_header_size,
++ .get_build = iwl4965_ucode_get_build,
++ .get_inst_size = iwl4965_ucode_get_inst_size,
++ .get_data_size = iwl4965_ucode_get_data_size,
++ .get_init_size = iwl4965_ucode_get_init_size,
++ .get_init_data_size = iwl4965_ucode_get_init_data_size,
++ .get_boot_size = iwl4965_ucode_get_boot_size,
++ .get_data = iwl4965_ucode_get_data,
++};
+ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
+ .get_hcmd_size = iwl4965_get_hcmd_size,
+ .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
+@@ -2287,6 +2325,7 @@ static struct iwl_lib_ops iwl4965_lib = {
+ };
+
+ static struct iwl_ops iwl4965_ops = {
++ .ucode = &iwl4965_ucode,
+ .lib = &iwl4965_lib,
+ .hcmd = &iwl4965_hcmd,
+ .utils = &iwl4965_hcmd_utils,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
+index b3c648c..a9ea3b5 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
+@@ -239,6 +239,13 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
+ APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
+ ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
+
++ if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_1000) {
++ /* Setting digital SVR for 1000 card to 1.32V */
++ iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
++ APMG_SVR_DIGITAL_VOLTAGE_1_32,
++ ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
++ }
++
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+@@ -1426,6 +1433,44 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
+ return max_rssi - agc - IWL49_RSSI_OFFSET;
+ }
+
++#define IWL5000_UCODE_GET(item) \
++static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
++ u32 api_ver) \
++{ \
++ if (api_ver <= 2) \
++ return le32_to_cpu(ucode->u.v1.item); \
++ return le32_to_cpu(ucode->u.v2.item); \
++}
++
++static u32 iwl5000_ucode_get_header_size(u32 api_ver)
++{
++ if (api_ver <= 2)
++ return UCODE_HEADER_SIZE(1);
++ return UCODE_HEADER_SIZE(2);
++}
++
++static u32 iwl5000_ucode_get_build(const struct iwl_ucode_header *ucode,
++ u32 api_ver)
++{
++ if (api_ver <= 2)
++ return 0;
++ return le32_to_cpu(ucode->u.v2.build);
++}
++
++static u8 *iwl5000_ucode_get_data(const struct iwl_ucode_header *ucode,
++ u32 api_ver)
++{
++ if (api_ver <= 2)
++ return (u8 *) ucode->u.v1.data;
++ return (u8 *) ucode->u.v2.data;
++}
++
++IWL5000_UCODE_GET(inst_size);
++IWL5000_UCODE_GET(data_size);
++IWL5000_UCODE_GET(init_size);
++IWL5000_UCODE_GET(init_data_size);
++IWL5000_UCODE_GET(boot_size);
++
+ struct iwl_hcmd_ops iwl5000_hcmd = {
+ .rxon_assoc = iwl5000_send_rxon_assoc,
+ .commit_rxon = iwl_commit_rxon,
+@@ -1441,6 +1486,17 @@ struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
+ .calc_rssi = iwl5000_calc_rssi,
+ };
+
++struct iwl_ucode_ops iwl5000_ucode = {
++ .get_header_size = iwl5000_ucode_get_header_size,
++ .get_build = iwl5000_ucode_get_build,
++ .get_inst_size = iwl5000_ucode_get_inst_size,
++ .get_data_size = iwl5000_ucode_get_data_size,
++ .get_init_size = iwl5000_ucode_get_init_size,
++ .get_init_data_size = iwl5000_ucode_get_init_data_size,
++ .get_boot_size = iwl5000_ucode_get_boot_size,
++ .get_data = iwl5000_ucode_get_data,
++};
++
+ struct iwl_lib_ops iwl5000_lib = {
+ .set_hw_params = iwl5000_hw_set_hw_params,
+ .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
+@@ -1542,12 +1598,14 @@ static struct iwl_lib_ops iwl5150_lib = {
+ };
+
+ struct iwl_ops iwl5000_ops = {
++ .ucode = &iwl5000_ucode,
+ .lib = &iwl5000_lib,
+ .hcmd = &iwl5000_hcmd,
+ .utils = &iwl5000_hcmd_utils,
+ };
+
+ static struct iwl_ops iwl5150_ops = {
++ .ucode = &iwl5000_ucode,
+ .lib = &iwl5150_lib,
+ .hcmd = &iwl5000_hcmd,
+ .utils = &iwl5000_hcmd_utils,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
+index bd438d8..e4a405f 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
+@@ -46,8 +46,8 @@
+ #include "iwl-5000-hw.h"
+
+ /* Highest firmware API version supported */
+-#define IWL6000_UCODE_API_MAX 2
+-#define IWL6050_UCODE_API_MAX 2
++#define IWL6000_UCODE_API_MAX 3
++#define IWL6050_UCODE_API_MAX 3
+
+ /* Lowest firmware API version supported */
+ #define IWL6000_UCODE_API_MIN 1
+@@ -69,6 +69,7 @@ static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
+ };
+
+ static struct iwl_ops iwl6000_ops = {
++ .ucode = &iwl5000_ucode,
+ .lib = &iwl5000_lib,
+ .hcmd = &iwl5000_hcmd,
+ .utils = &iwl6000_hcmd_utils,
+@@ -81,13 +82,15 @@ struct iwl_cfg iwl6000_2ag_cfg = {
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G,
+ .ops = &iwl6000_ops,
+- .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
++ .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
++ .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
++ .shadow_ram_support = true,
+ };
+
+ struct iwl_cfg iwl6000_2agn_cfg = {
+@@ -97,13 +100,15 @@ struct iwl_cfg iwl6000_2agn_cfg = {
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+- .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
++ .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = false,
++ .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
++ .shadow_ram_support = true,
+ };
+
+ struct iwl_cfg iwl6050_2agn_cfg = {
+@@ -113,13 +118,15 @@ struct iwl_cfg iwl6050_2agn_cfg = {
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+- .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
++ .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_AB,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = false,
++ .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
++ .shadow_ram_support = true,
+ };
+
+ struct iwl_cfg iwl6000_3agn_cfg = {
+@@ -129,13 +136,15 @@ struct iwl_cfg iwl6000_3agn_cfg = {
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+- .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
++ .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = false,
++ .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
++ .shadow_ram_support = true,
+ };
+
+ struct iwl_cfg iwl6050_3agn_cfg = {
+@@ -145,13 +154,15 @@ struct iwl_cfg iwl6050_3agn_cfg = {
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+- .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
++ .eeprom_size = OTP_LOW_IMAGE_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = false,
++ .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
++ .shadow_ram_support = true,
+ };
+
+ MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
+index 355f50e..2a577ae 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -1348,7 +1348,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
+ */
+ static int iwl_read_ucode(struct iwl_priv *priv)
+ {
+- struct iwl_ucode *ucode;
++ struct iwl_ucode_header *ucode;
+ int ret = -EINVAL, index;
+ const struct firmware *ucode_raw;
+ const char *name_pre = priv->cfg->fw_name_pre;
+@@ -1357,7 +1357,8 @@ static int iwl_read_ucode(struct iwl_priv *priv)
+ char buf[25];
+ u8 *src;
+ size_t len;
+- u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
++ u32 api_ver, build;
++ u32 inst_size, data_size, init_size, init_data_size, boot_size;
+
+ /* Ask kernel firmware_class module to get the boot firmware off disk.
+ * request_firmware() is synchronous, file is in memory on return. */
+@@ -1387,23 +1388,26 @@ static int iwl_read_ucode(struct iwl_priv *priv)
+ if (ret < 0)
+ goto error;
+
+- /* Make sure that we got at least our header! */
+- if (ucode_raw->size < sizeof(*ucode)) {
++ /* Make sure that we got at least the v1 header! */
++ if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
+ IWL_ERR(priv, "File size way too small!\n");
+ ret = -EINVAL;
+ goto err_release;
+ }
+
+ /* Data from ucode file: header followed by uCode images */
+- ucode = (void *)ucode_raw->data;
++ ucode = (struct iwl_ucode_header *)ucode_raw->data;
+
+ priv->ucode_ver = le32_to_cpu(ucode->ver);
+ api_ver = IWL_UCODE_API(priv->ucode_ver);
+- inst_size = le32_to_cpu(ucode->inst_size);
+- data_size = le32_to_cpu(ucode->data_size);
+- init_size = le32_to_cpu(ucode->init_size);
+- init_data_size = le32_to_cpu(ucode->init_data_size);
+- boot_size = le32_to_cpu(ucode->boot_size);
++ build = priv->cfg->ops->ucode->get_build(ucode, api_ver);
++ inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
++ data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
++ init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
++ init_data_size =
++ priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
++ boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
++ src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
+
+ /* api_ver should match the api version forming part of the
+ * firmware filename ... but we don't check for that and only rely
+@@ -1429,6 +1433,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver));
+
++ if (build)
++ IWL_DEBUG_INFO(priv, "Build %u\n", build);
++
+ IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
+ priv->ucode_ver);
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
+@@ -1443,12 +1450,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
+ boot_size);
+
+ /* Verify size of file vs. image size info in file's header */
+- if (ucode_raw->size < sizeof(*ucode) +
++ if (ucode_raw->size !=
++ priv->cfg->ops->ucode->get_header_size(api_ver) +
+ inst_size + data_size + init_size +
+ init_data_size + boot_size) {
+
+- IWL_DEBUG_INFO(priv, "uCode file size %d too small\n",
+- (int)ucode_raw->size);
++ IWL_DEBUG_INFO(priv,
++ "uCode file size %d does not match expected size\n",
++ (int)ucode_raw->size);
+ ret = -EINVAL;
+ goto err_release;
+ }
+@@ -1528,42 +1537,42 @@ static int iwl_read_ucode(struct iwl_priv *priv)
+ /* Copy images into buffers for card's bus-master reads ... */
+
+ /* Runtime instructions (first block of data in file) */
+- src = &ucode->data[0];
+- len = priv->ucode_code.len;
++ len = inst_size;
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
+ memcpy(priv->ucode_code.v_addr, src, len);
++ src += len;
++
+ IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+ priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
+
+ /* Runtime data (2nd block)
+ * NOTE: Copy into backup buffer will be done in iwl_up() */
+- src = &ucode->data[inst_size];
+- len = priv->ucode_data.len;
++ len = data_size;
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
+ memcpy(priv->ucode_data.v_addr, src, len);
+ memcpy(priv->ucode_data_backup.v_addr, src, len);
++ src += len;
+
+ /* Initialization instructions (3rd block) */
+ if (init_size) {
+- src = &ucode->data[inst_size + data_size];
+- len = priv->ucode_init.len;
++ len = init_size;
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
+ len);
+ memcpy(priv->ucode_init.v_addr, src, len);
++ src += len;
+ }
+
+ /* Initialization data (4th block) */
+ if (init_data_size) {
+- src = &ucode->data[inst_size + data_size + init_size];
+- len = priv->ucode_init_data.len;
++ len = init_data_size;
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
+ len);
+ memcpy(priv->ucode_init_data.v_addr, src, len);
++ src += len;
+ }
+
+ /* Bootstrap instructions (5th block) */
+- src = &ucode->data[inst_size + data_size + init_size + init_data_size];
+- len = priv->ucode_boot.len;
++ len = boot_size;
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
+ memcpy(priv->ucode_boot.v_addr, src, len);
+
+@@ -2206,7 +2215,7 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
+
+ priv->is_open = 0;
+
+- if (iwl_is_ready_rf(priv)) {
++ if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) {
+ /* stop mac, cancel any scan request and clear
+ * RXON_FILTER_ASSOC_MSK BIT
+ */
+diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
+index dabf663..1e51891 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-core.h
++++ b/drivers/net/wireless/iwlwifi/iwl-core.h
+@@ -116,6 +116,17 @@ struct iwl_temp_ops {
+ void (*set_ct_kill)(struct iwl_priv *priv);
+ };
+
++struct iwl_ucode_ops {
++ u32 (*get_header_size)(u32);
++ u32 (*get_build)(const struct iwl_ucode_header *, u32);
++ u32 (*get_inst_size)(const struct iwl_ucode_header *, u32);
++ u32 (*get_data_size)(const struct iwl_ucode_header *, u32);
++ u32 (*get_init_size)(const struct iwl_ucode_header *, u32);
++ u32 (*get_init_data_size)(const struct iwl_ucode_header *, u32);
++ u32 (*get_boot_size)(const struct iwl_ucode_header *, u32);
++ u8 * (*get_data)(const struct iwl_ucode_header *, u32);
++};
++
+ struct iwl_lib_ops {
+ /* set hw dependent parameters */
+ int (*set_hw_params)(struct iwl_priv *priv);
+@@ -171,6 +182,7 @@ struct iwl_lib_ops {
+ };
+
+ struct iwl_ops {
++ const struct iwl_ucode_ops *ucode;
+ const struct iwl_lib_ops *lib;
+ const struct iwl_hcmd_ops *hcmd;
+ const struct iwl_hcmd_utils_ops *utils;
+@@ -195,6 +207,8 @@ struct iwl_mod_params {
+ * filename is constructed as fw_name_pre<api>.ucode.
+ * @ucode_api_max: Highest version of uCode API supported by driver.
+ * @ucode_api_min: Lowest version of uCode API supported by driver.
++ * @max_ll_items: max number of OTP blocks
++ * @shadow_ram_support: shadow support for OTP memory
+ *
+ * We enable the driver to be backward compatible wrt API version. The
+ * driver specifies which APIs it supports (with @ucode_api_max being the
+@@ -231,6 +245,8 @@ struct iwl_cfg {
+ u8 valid_rx_ant;
+ bool need_pll_cfg;
+ bool use_isr_legacy;
++ const u16 max_ll_items;
++ const bool shadow_ram_support;
+ };
+
+ /***************************
+diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
+index 650e20a..e8c8607 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
+@@ -66,6 +66,7 @@ extern struct iwl_cfg iwl1000_bgn_cfg;
+ /* shared structures from iwl-5000.c */
+ extern struct iwl_mod_params iwl50_mod_params;
+ extern struct iwl_ops iwl5000_ops;
++extern struct iwl_ucode_ops iwl5000_ucode;
+ extern struct iwl_lib_ops iwl5000_lib;
+ extern struct iwl_hcmd_ops iwl5000_hcmd;
+ extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
+@@ -525,15 +526,29 @@ struct fw_desc {
+ };
+
+ /* uCode file layout */
+-struct iwl_ucode {
+- __le32 ver; /* major/minor/API/serial */
+- __le32 inst_size; /* bytes of runtime instructions */
+- __le32 data_size; /* bytes of runtime data */
+- __le32 init_size; /* bytes of initialization instructions */
+- __le32 init_data_size; /* bytes of initialization data */
+- __le32 boot_size; /* bytes of bootstrap instructions */
+- u8 data[0]; /* data in same order as "size" elements */
++struct iwl_ucode_header {
++ __le32 ver; /* major/minor/API/serial */
++ union {
++ struct {
++ __le32 inst_size; /* bytes of runtime code */
++ __le32 data_size; /* bytes of runtime data */
++ __le32 init_size; /* bytes of init code */
++ __le32 init_data_size; /* bytes of init data */
++ __le32 boot_size; /* bytes of bootstrap code */
++ u8 data[0]; /* in same order as sizes */
++ } v1;
++ struct {
++ __le32 build; /* build number */
++ __le32 inst_size; /* bytes of runtime code */
++ __le32 data_size; /* bytes of runtime data */
++ __le32 init_size; /* bytes of init code */
++ __le32 init_data_size; /* bytes of init data */
++ __le32 boot_size; /* bytes of bootstrap code */
++ u8 data[0]; /* in same order as sizes */
++ } v2;
++ } u;
+ };
++#define UCODE_HEADER_SIZE(ver) ((ver) == 1 ? 24 : 28)
+
+ struct iwl4965_ibss_seq {
+ u8 mac[ETH_ALEN];
+@@ -820,6 +835,18 @@ enum iwl_nvm_type {
+ NVM_DEVICE_TYPE_OTP,
+ };
+
++/*
++ * Two types of OTP memory access modes
++ * IWL_OTP_ACCESS_ABSOLUTE - absolute address mode,
++ * based on physical memory addressing
++ * IWL_OTP_ACCESS_RELATIVE - relative address mode,
++ * based on logical memory addressing
++ */
++enum iwl_access_mode {
++ IWL_OTP_ACCESS_ABSOLUTE,
++ IWL_OTP_ACCESS_RELATIVE,
++};
++
+ /* interrupt statistics */
+ struct isr_statistics {
+ u32 hw;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+index 7d7554a..e8c0e82 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+@@ -152,6 +152,19 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
+ }
+ EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
+
++static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
++{
++ u32 otpgp;
++
++ otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
++ if (mode == IWL_OTP_ACCESS_ABSOLUTE)
++ iwl_clear_bit(priv, CSR_OTP_GP_REG,
++ CSR_OTP_GP_REG_OTP_ACCESS_MODE);
++ else
++ iwl_set_bit(priv, CSR_OTP_GP_REG,
++ CSR_OTP_GP_REG_OTP_ACCESS_MODE);
++}
++
+ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
+ {
+ u32 otpgp;
+@@ -249,6 +262,124 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
+ return ret;
+ }
+
++static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
++{
++ int ret = 0;
++ u32 r;
++ u32 otpgp;
++
++ _iwl_write32(priv, CSR_EEPROM_REG,
++ CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
++ ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
++ CSR_EEPROM_REG_READ_VALID_MSK,
++ IWL_EEPROM_ACCESS_TIMEOUT);
++ if (ret < 0) {
++ IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
++ return ret;
++ }
++ r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
++ /* check for ECC errors: */
++ otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
++ if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
++ /* stop in this case */
++ /* set the uncorrectable OTP ECC bit for acknowledgement */
++ iwl_set_bit(priv, CSR_OTP_GP_REG,
++ CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
++ IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n");
++ return -EINVAL;
++ }
++ if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
++ /* continue in this case */
++ /* set the correctable OTP ECC bit for acknowledgement */
++ iwl_set_bit(priv, CSR_OTP_GP_REG,
++ CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
++ IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
++ }
++ *eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
++ return 0;
++}
++
++/*
++ * iwl_is_otp_empty: check for empty OTP
++ */
++static bool iwl_is_otp_empty(struct iwl_priv *priv)
++{
++ u16 next_link_addr = 0, link_value;
++ bool is_empty = false;
++
++ /* locate the beginning of OTP link list */
++ if (!iwl_read_otp_word(priv, next_link_addr, &link_value)) {
++ if (!link_value) {
++ IWL_ERR(priv, "OTP is empty\n");
++ is_empty = true;
++ }
++ } else {
++ IWL_ERR(priv, "Unable to read first block of OTP list.\n");
++ is_empty = true;
++ }
++
++ return is_empty;
++}
++
++
++/*
++ * iwl_find_otp_image: find EEPROM image in OTP
++ * finding the OTP block that contains the EEPROM image.
++ * the last valid block on the link list (the block _before_ the last block)
++ * is the block we should read and used to configure the device.
++ * If all the available OTP blocks are full, the last block will be the block
++ * we should read and used to configure the device.
++ * only perform this operation if shadow RAM is disabled
++ */
++static int iwl_find_otp_image(struct iwl_priv *priv,
++ u16 *validblockaddr)
++{
++ u16 next_link_addr = 0, link_value = 0, valid_addr;
++ int ret = 0;
++ int usedblocks = 0;
++
++ /* set addressing mode to absolute to traverse the link list */
++ iwl_set_otp_access(priv, IWL_OTP_ACCESS_ABSOLUTE);
++
++ /* checking for empty OTP or error */
++ if (iwl_is_otp_empty(priv))
++ return -EINVAL;
++
++ /*
++ * start traverse link list
++ * until reach the max number of OTP blocks
++ * different devices have different number of OTP blocks
++ */
++ do {
++ /* save current valid block address
++ * check for more block on the link list
++ */
++ valid_addr = next_link_addr;
++ next_link_addr = link_value;
++ IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
++ usedblocks, next_link_addr);
++ if (iwl_read_otp_word(priv, next_link_addr, &link_value))
++ return -EINVAL;
++ if (!link_value) {
++ /*
++ * reach the end of link list,
++ * set address point to the starting address
++ * of the image
++ */
++ goto done;
++ }
++ /* more in the link list, continue */
++ usedblocks++;
++ } while (usedblocks < priv->cfg->max_ll_items);
++ /* OTP full, use last block */
++ IWL_DEBUG_INFO(priv, "OTP is full, use last block\n");
++done:
++ *validblockaddr = valid_addr;
++ /* skip first 2 bytes (link list pointer) */
++ *validblockaddr += 2;
++ return ret;
++}
++
+ /**
+ * iwl_eeprom_init - read EEPROM contents
+ *
+@@ -263,14 +394,13 @@ int iwl_eeprom_init(struct iwl_priv *priv)
+ int sz;
+ int ret;
+ u16 addr;
+- u32 otpgp;
++ u16 validblockaddr = 0;
++ u16 cache_addr = 0;
+
+ priv->nvm_device_type = iwlcore_get_nvm_type(priv);
+
+ /* allocate eeprom */
+- if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+- priv->cfg->eeprom_size =
+- OTP_BLOCK_SIZE * OTP_LOWER_BLOCKS_TOTAL;
++ IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size);
+ sz = priv->cfg->eeprom_size;
+ priv->eeprom = kzalloc(sz, GFP_KERNEL);
+ if (!priv->eeprom) {
+@@ -298,46 +428,31 @@ int iwl_eeprom_init(struct iwl_priv *priv)
+ if (ret) {
+ IWL_ERR(priv, "Failed to initialize OTP access.\n");
+ ret = -ENOENT;
+- goto err;
++ goto done;
+ }
+ _iwl_write32(priv, CSR_EEPROM_GP,
+ iwl_read32(priv, CSR_EEPROM_GP) &
+ ~CSR_EEPROM_GP_IF_OWNER_MSK);
+- /* clear */
+- _iwl_write32(priv, CSR_OTP_GP_REG,
+- iwl_read32(priv, CSR_OTP_GP_REG) |
++
++ iwl_set_bit(priv, CSR_OTP_GP_REG,
+ CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
+ CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
+-
+- for (addr = 0; addr < sz; addr += sizeof(u16)) {
+- u32 r;
+-
+- _iwl_write32(priv, CSR_EEPROM_REG,
+- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+-
+- ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+- CSR_EEPROM_REG_READ_VALID_MSK,
+- IWL_EEPROM_ACCESS_TIMEOUT);
+- if (ret < 0) {
+- IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
++ /* traversing the linked list if no shadow ram supported */
++ if (!priv->cfg->shadow_ram_support) {
++ if (iwl_find_otp_image(priv, &validblockaddr)) {
++ ret = -ENOENT;
+ goto done;
+ }
+- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+- /* check for ECC errors: */
+- otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
+- if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
+- /* stop in this case */
+- IWL_ERR(priv, "Uncorrectable OTP ECC error, Abort OTP read\n");
++ }
++ for (addr = validblockaddr; addr < validblockaddr + sz;
++ addr += sizeof(u16)) {
++ u16 eeprom_data;
++
++ ret = iwl_read_otp_word(priv, addr, &eeprom_data);
++ if (ret)
+ goto done;
+- }
+- if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
+- /* continue in this case */
+- _iwl_write32(priv, CSR_OTP_GP_REG,
+- iwl_read32(priv, CSR_OTP_GP_REG) |
+- CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
+- IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
+- }
+- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
++ e[cache_addr / 2] = eeprom_data;
++ cache_addr += sizeof(u16);
+ }
+ } else {
+ /* eeprom is an array of 16bit values */
+diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+index 195b4ef..7899885 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+@@ -180,8 +180,14 @@ struct iwl_eeprom_channel {
+ #define EEPROM_5050_EEPROM_VERSION (0x21E)
+
+ /* OTP */
+-#define OTP_LOWER_BLOCKS_TOTAL (3)
+-#define OTP_BLOCK_SIZE (0x400)
++/* lower blocks contain EEPROM image and calibration data */
++#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
++/* high blocks contain PAPD data */
++#define OTP_HIGH_IMAGE_SIZE_6x00 (6 * 512 * sizeof(u16)) /* 6 KB */
++#define OTP_HIGH_IMAGE_SIZE_1000 (0x200 * sizeof(u16)) /* 1024 bytes */
++#define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */
++#define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */
++#define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */
+
+ /* 2.4 GHz */
+ extern const u8 iwl_eeprom_band_1[14];
+diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
+index 3b9cac3..d393e8f 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
++++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
+@@ -80,6 +80,8 @@
+ #define APMG_RFKILL_REG (APMG_BASE + 0x0014)
+ #define APMG_RTC_INT_STT_REG (APMG_BASE + 0x001c)
+ #define APMG_RTC_INT_MSK_REG (APMG_BASE + 0x0020)
++#define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058)
++#define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C)
+
+ #define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
+ #define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800)
+@@ -91,7 +93,8 @@
+ #define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
+ #define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */
+ #define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000)
+-
++#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */
++#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060)
+
+ #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
+index e26875d..474fd49 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
++++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
+@@ -799,7 +799,8 @@ void iwl_bg_abort_scan(struct work_struct *work)
+ {
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
+
+- if (!iwl_is_ready(priv))
++ if (!test_bit(STATUS_READY, &priv->status) ||
++ !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
+ return;
+
+ mutex_lock(&priv->mutex);
+diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+index 5238433..054d6c7 100644
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -2111,7 +2111,7 @@ static void iwl3945_nic_start(struct iwl_priv *priv)
+ */
+ static int iwl3945_read_ucode(struct iwl_priv *priv)
+ {
+- struct iwl_ucode *ucode;
++ const struct iwl_ucode_header *ucode;
+ int ret = -EINVAL, index;
+ const struct firmware *ucode_raw;
+ /* firmware file name contains uCode/driver compatibility version */
+@@ -2152,22 +2152,24 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
+ goto error;
+
+ /* Make sure that we got at least our header! */
+- if (ucode_raw->size < sizeof(*ucode)) {
++ if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
+ IWL_ERR(priv, "File size way too small!\n");
+ ret = -EINVAL;
+ goto err_release;
+ }
+
+ /* Data from ucode file: header followed by uCode images */
+- ucode = (void *)ucode_raw->data;
++ ucode = (struct iwl_ucode_header *)ucode_raw->data;
+
+ priv->ucode_ver = le32_to_cpu(ucode->ver);
+ api_ver = IWL_UCODE_API(priv->ucode_ver);
+- inst_size = le32_to_cpu(ucode->inst_size);
+- data_size = le32_to_cpu(ucode->data_size);
+- init_size = le32_to_cpu(ucode->init_size);
+- init_data_size = le32_to_cpu(ucode->init_data_size);
+- boot_size = le32_to_cpu(ucode->boot_size);
++ inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
++ data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
++ init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
++ init_data_size =
++ priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
++ boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
++ src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
+
+ /* api_ver should match the api version forming part of the
+ * firmware filename ... but we don't check for that and only rely
+@@ -2208,12 +2210,13 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
+
+
+ /* Verify size of file vs. image size info in file's header */
+- if (ucode_raw->size < sizeof(*ucode) +
++ if (ucode_raw->size != priv->cfg->ops->ucode->get_header_size(api_ver) +
+ inst_size + data_size + init_size +
+ init_data_size + boot_size) {
+
+- IWL_DEBUG_INFO(priv, "uCode file size %zd too small\n",
+- ucode_raw->size);
++ IWL_DEBUG_INFO(priv,
++ "uCode file size %zd does not match expected size\n",
++ ucode_raw->size);
+ ret = -EINVAL;
+ goto err_release;
+ }
+@@ -2296,44 +2299,44 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
+ /* Copy images into buffers for card's bus-master reads ... */
+
+ /* Runtime instructions (first block of data in file) */
+- src = &ucode->data[0];
+- len = priv->ucode_code.len;
++ len = inst_size;
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) uCode instr len %zd\n", len);
+ memcpy(priv->ucode_code.v_addr, src, len);
++ src += len;
++
+ IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+ priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
+
+ /* Runtime data (2nd block)
+ * NOTE: Copy into backup buffer will be done in iwl3945_up() */
+- src = &ucode->data[inst_size];
+- len = priv->ucode_data.len;
++ len = data_size;
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) uCode data len %zd\n", len);
+ memcpy(priv->ucode_data.v_addr, src, len);
+ memcpy(priv->ucode_data_backup.v_addr, src, len);
++ src += len;
+
+ /* Initialization instructions (3rd block) */
+ if (init_size) {
+- src = &ucode->data[inst_size + data_size];
+- len = priv->ucode_init.len;
++ len = init_size;
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) init instr len %zd\n", len);
+ memcpy(priv->ucode_init.v_addr, src, len);
++ src += len;
+ }
+
+ /* Initialization data (4th block) */
+ if (init_data_size) {
+- src = &ucode->data[inst_size + data_size + init_size];
+- len = priv->ucode_init_data.len;
++ len = init_data_size;
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) init data len %zd\n", len);
+ memcpy(priv->ucode_init_data.v_addr, src, len);
++ src += len;
+ }
+
+ /* Bootstrap instructions (5th block) */
+- src = &ucode->data[inst_size + data_size + init_size + init_data_size];
+- len = priv->ucode_boot.len;
++ len = boot_size;
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) boot instr len %zd\n", len);
+ memcpy(priv->ucode_boot.v_addr, src, len);
+diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
+index 0e877a1..6e1b889 100644
+--- a/drivers/net/wireless/p54/p54usb.c
++++ b/drivers/net/wireless/p54/p54usb.c
+@@ -66,6 +66,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
+ {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
+ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
+ {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
++ {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */
+ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
+ {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
+ {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
+diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
+index 9e1140f..e1dcced 100644
+--- a/drivers/pcmcia/at91_cf.c
++++ b/drivers/pcmcia/at91_cf.c
+@@ -363,7 +363,7 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
+ struct at91_cf_socket *cf = platform_get_drvdata(pdev);
+ struct at91_cf_data *board = cf->board;
+
+- pcmcia_socket_dev_suspend(&pdev->dev, mesg);
++ pcmcia_socket_dev_suspend(&pdev->dev);
+ if (device_may_wakeup(&pdev->dev)) {
+ enable_irq_wake(board->det_pin);
+ if (board->irq_pin)
+diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
+index 9001334..0208870 100644
+--- a/drivers/pcmcia/au1000_generic.c
++++ b/drivers/pcmcia/au1000_generic.c
+@@ -515,7 +515,7 @@ static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
+ static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c
+index b59d411..300b368 100644
+--- a/drivers/pcmcia/bfin_cf_pcmcia.c
++++ b/drivers/pcmcia/bfin_cf_pcmcia.c
+@@ -302,7 +302,7 @@ static int __devexit bfin_cf_remove(struct platform_device *pdev)
+
+ static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
+ {
+- return pcmcia_socket_dev_suspend(&pdev->dev, mesg);
++ return pcmcia_socket_dev_suspend(&pdev->dev);
+ }
+
+ static int bfin_cf_resume(struct platform_device *pdev)
+diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
+index 0660ad1..934d4be 100644
+--- a/drivers/pcmcia/cs.c
++++ b/drivers/pcmcia/cs.c
+@@ -101,7 +101,7 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
+ static int socket_resume(struct pcmcia_socket *skt);
+ static int socket_suspend(struct pcmcia_socket *skt);
+
+-int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
++int pcmcia_socket_dev_suspend(struct device *dev)
+ {
+ struct pcmcia_socket *socket;
+
+diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
+index 46561fa..a04f21c 100644
+--- a/drivers/pcmcia/i82092.c
++++ b/drivers/pcmcia/i82092.c
+@@ -42,7 +42,7 @@ MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
+ #ifdef CONFIG_PM
+ static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int i82092aa_socket_resume (struct pci_dev *dev)
+diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
+index 40d4953..b906abe 100644
+--- a/drivers/pcmcia/i82365.c
++++ b/drivers/pcmcia/i82365.c
+@@ -1241,7 +1241,7 @@ static int pcic_init(struct pcmcia_socket *s)
+ static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int i82365_drv_pcmcia_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
+index 62b4ecc..d1d89c4 100644
+--- a/drivers/pcmcia/m32r_cfc.c
++++ b/drivers/pcmcia/m32r_cfc.c
+@@ -699,7 +699,7 @@ static struct pccard_operations pcc_operations = {
+ static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int cfc_drv_pcmcia_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
+index 12034b4..a065583 100644
+--- a/drivers/pcmcia/m32r_pcc.c
++++ b/drivers/pcmcia/m32r_pcc.c
+@@ -675,7 +675,7 @@ static struct pccard_operations pcc_operations = {
+ static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int pcc_drv_pcmcia_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
+index d1ad096..c69f2c4 100644
+--- a/drivers/pcmcia/m8xx_pcmcia.c
++++ b/drivers/pcmcia/m8xx_pcmcia.c
+@@ -1296,7 +1296,7 @@ static int m8xx_remove(struct of_device *ofdev)
+ #ifdef CONFIG_PM
+ static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&pdev->dev, state);
++ return pcmcia_socket_dev_suspend(&pdev->dev);
+ }
+
+ static int m8xx_resume(struct platform_device *pdev)
+diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
+index f373639..68570bc 100644
+--- a/drivers/pcmcia/omap_cf.c
++++ b/drivers/pcmcia/omap_cf.c
+@@ -334,7 +334,7 @@ static int __exit omap_cf_remove(struct platform_device *pdev)
+
+ static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
+ {
+- return pcmcia_socket_dev_suspend(&pdev->dev, mesg);
++ return pcmcia_socket_dev_suspend(&pdev->dev);
+ }
+
+ static int omap_cf_resume(struct platform_device *pdev)
+diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
+index 8bed1da..1c39d34 100644
+--- a/drivers/pcmcia/pd6729.c
++++ b/drivers/pcmcia/pd6729.c
+@@ -758,7 +758,7 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev)
+ #ifdef CONFIG_PM
+ static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int pd6729_socket_resume(struct pci_dev *dev)
+diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
+index c49a726..86ad876 100644
+--- a/drivers/pcmcia/pxa2xx_base.c
++++ b/drivers/pcmcia/pxa2xx_base.c
+@@ -302,7 +302,7 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
+
+ static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
+index d8da5ac..2d0e997 100644
+--- a/drivers/pcmcia/sa1100_generic.c
++++ b/drivers/pcmcia/sa1100_generic.c
+@@ -89,7 +89,7 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+ static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
+index 401052a..4be4e17 100644
+--- a/drivers/pcmcia/sa1111_generic.c
++++ b/drivers/pcmcia/sa1111_generic.c
+@@ -159,7 +159,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
+
+ static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int pcmcia_resume(struct sa1111_dev *dev)
+diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
+index 8eb0423..582413f 100644
+--- a/drivers/pcmcia/tcic.c
++++ b/drivers/pcmcia/tcic.c
+@@ -366,7 +366,7 @@ static int __init get_tcic_id(void)
+ static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int tcic_drv_pcmcia_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
+index d4ad50d..c9fcbdc 100644
+--- a/drivers/pcmcia/vrc4171_card.c
++++ b/drivers/pcmcia/vrc4171_card.c
+@@ -707,7 +707,7 @@ __setup("vrc4171_card=", vrc4171_card_setup);
+ static int vrc4171_card_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+- return pcmcia_socket_dev_suspend(&dev->dev, state);
++ return pcmcia_socket_dev_suspend(&dev->dev);
+ }
+
+ static int vrc4171_card_resume(struct platform_device *dev)
+diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
+index 3ecd7c9..f728a45 100644
+--- a/drivers/pcmcia/yenta_socket.c
++++ b/drivers/pcmcia/yenta_socket.c
+@@ -1225,60 +1225,71 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
+ }
+
+ #ifdef CONFIG_PM
+-static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
++static int yenta_dev_suspend_noirq(struct device *dev)
+ {
+- struct yenta_socket *socket = pci_get_drvdata(dev);
++ struct pci_dev *pdev = to_pci_dev(dev);
++ struct yenta_socket *socket = pci_get_drvdata(pdev);
+ int ret;
+
+- ret = pcmcia_socket_dev_suspend(&dev->dev, state);
++ ret = pcmcia_socket_dev_suspend(dev);
+
+- if (socket) {
+- if (socket->type && socket->type->save_state)
+- socket->type->save_state(socket);
++ if (!socket)
++ return ret;
+
+- /* FIXME: pci_save_state needs to have a better interface */
+- pci_save_state(dev);
+- pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
+- pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
+- pci_disable_device(dev);
++ if (socket->type && socket->type->save_state)
++ socket->type->save_state(socket);
+
+- /*
+- * Some laptops (IBM T22) do not like us putting the Cardbus
+- * bridge into D3. At a guess, some other laptop will
+- * probably require this, so leave it commented out for now.
+- */
+- /* pci_set_power_state(dev, 3); */
+- }
++ pci_save_state(pdev);
++ pci_read_config_dword(pdev, 16*4, &socket->saved_state[0]);
++ pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]);
++ pci_disable_device(pdev);
++
++ /*
++ * Some laptops (IBM T22) do not like us putting the Cardbus
++ * bridge into D3. At a guess, some other laptop will
++ * probably require this, so leave it commented out for now.
++ */
++ /* pci_set_power_state(dev, 3); */
+
+ return ret;
+ }
+
+-
+-static int yenta_dev_resume (struct pci_dev *dev)
++static int yenta_dev_resume_noirq(struct device *dev)
+ {
+- struct yenta_socket *socket = pci_get_drvdata(dev);
++ struct pci_dev *pdev = to_pci_dev(dev);
++ struct yenta_socket *socket = pci_get_drvdata(pdev);
++ int ret;
+
+- if (socket) {
+- int rc;
++ if (!socket)
++ return 0;
+
+- pci_set_power_state(dev, 0);
+- /* FIXME: pci_restore_state needs to have a better interface */
+- pci_restore_state(dev);
+- pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
+- pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
++ pci_write_config_dword(pdev, 16*4, socket->saved_state[0]);
++ pci_write_config_dword(pdev, 17*4, socket->saved_state[1]);
+
+- rc = pci_enable_device(dev);
+- if (rc)
+- return rc;
++ ret = pci_enable_device(pdev);
++ if (ret)
++ return ret;
+
+- pci_set_master(dev);
++ pci_set_master(pdev);
+
+- if (socket->type && socket->type->restore_state)
+- socket->type->restore_state(socket);
+- }
++ if (socket->type && socket->type->restore_state)
++ socket->type->restore_state(socket);
+
+- return pcmcia_socket_dev_resume(&dev->dev);
++ return pcmcia_socket_dev_resume(dev);
+ }
++
++static struct dev_pm_ops yenta_pm_ops = {
++ .suspend_noirq = yenta_dev_suspend_noirq,
++ .resume_noirq = yenta_dev_resume_noirq,
++ .freeze_noirq = yenta_dev_suspend_noirq,
++ .thaw_noirq = yenta_dev_resume_noirq,
++ .poweroff_noirq = yenta_dev_suspend_noirq,
++ .restore_noirq = yenta_dev_resume_noirq,
++};
++
++#define YENTA_PM_OPS (¥ta_pm_ops)
++#else
++#define YENTA_PM_OPS NULL
+ #endif
+
+ #define CB_ID(vend,dev,type) \
+@@ -1376,10 +1387,7 @@ static struct pci_driver yenta_cardbus_driver = {
+ .id_table = yenta_table,
+ .probe = yenta_probe,
+ .remove = __devexit_p(yenta_close),
+-#ifdef CONFIG_PM
+- .suspend = yenta_dev_suspend,
+- .resume = yenta_dev_resume,
+-#endif
++ .driver.pm = YENTA_PM_OPS,
+ };
+
+
+diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
+index dafaa4a..a234a9d 100644
+--- a/drivers/platform/x86/sony-laptop.c
++++ b/drivers/platform/x86/sony-laptop.c
+@@ -1081,6 +1081,8 @@ static int sony_nc_setup_rfkill(struct acpi_device *device,
+ struct rfkill *rfk;
+ enum rfkill_type type;
+ const char *name;
++ int result;
++ bool hwblock;
+
+ switch (nc_type) {
+ case SONY_WIFI:
+@@ -1108,6 +1110,10 @@ static int sony_nc_setup_rfkill(struct acpi_device *device,
+ if (!rfk)
+ return -ENOMEM;
+
++ sony_call_snc_handle(0x124, 0x200, &result);
++ hwblock = !(result & 0x1);
++ rfkill_set_hw_state(rfk, hwblock);
++
+ err = rfkill_register(rfk);
+ if (err) {
+ rfkill_destroy(rfk);
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index e856008..d287283 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -5655,16 +5655,16 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
+ /* Models with ATI GPUs known to require ECNVRAM mode */
+ TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */
+
+- /* Models with ATI GPUs (waiting confirmation) */
+- TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
++ /* Models with ATI GPUs that can use ECNVRAM */
++ TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),
+ TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+ TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+ TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
+
+- /* Models with Intel Extreme Graphics 2 (waiting confirmation) */
++ /* Models with Intel Extreme Graphics 2 */
++ TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
+ TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
+ TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
+- TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
+
+ /* Models with Intel GMA900 */
+ TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */
+diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
+index b4a7650..4fff4e5 100644
+--- a/drivers/serial/bfin_5xx.c
++++ b/drivers/serial/bfin_5xx.c
+@@ -42,6 +42,10 @@
+ # undef CONFIG_EARLY_PRINTK
+ #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
+diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
+index 79c9c5f..6ecb51b 100644
+--- a/drivers/serial/serial_cs.c
++++ b/drivers/serial/serial_cs.c
+@@ -884,6 +884,7 @@ static struct pcmcia_device_id serial_ids[] = {
+ PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
+ PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
+ PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
++ PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "COMpad2.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 2bfc41e..e3861b2 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -59,6 +59,7 @@
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/tty.h>
++#include <linux/serial.h>
+ #include <linux/tty_driver.h>
+ #include <linux/tty_flip.h>
+ #include <linux/module.h>
+@@ -609,6 +610,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
+ acm->throttle = 0;
+
+ tasklet_schedule(&acm->urb_task);
++ set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
+ rv = tty_port_block_til_ready(&acm->port, tty, filp);
+ done:
+ mutex_unlock(&acm->mutex);
+@@ -858,10 +860,7 @@ static void acm_tty_set_termios(struct tty_struct *tty,
+ if (!ACM_READY(acm))
+ return;
+
+- /* FIXME: Needs to support the tty_baud interface */
+- /* FIXME: Broken on sparc */
+- newline.dwDTERate = cpu_to_le32p(acm_tty_speed +
+- (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0));
++ newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
+ newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
+ newline.bParityType = termios->c_cflag & PARENB ?
+ (termios->c_cflag & PARODD ? 1 : 2) +
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index ba589d4..a9c3399 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -313,8 +313,13 @@ static ssize_t wdm_write
+ r = usb_autopm_get_interface(desc->intf);
+ if (r < 0)
+ goto outnp;
+- r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
+- &desc->flags));
++
++ if (!file->f_flags && O_NONBLOCK)
++ r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
++ &desc->flags));
++ else
++ if (test_bit(WDM_IN_USE, &desc->flags))
++ r = -EAGAIN;
+ if (r < 0)
+ goto out;
+
+@@ -377,7 +382,7 @@ outnl:
+ static ssize_t wdm_read
+ (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
+ {
+- int rv, cntr;
++ int rv, cntr = 0;
+ int i = 0;
+ struct wdm_device *desc = file->private_data;
+
+@@ -389,10 +394,23 @@ static ssize_t wdm_read
+ if (desc->length == 0) {
+ desc->read = 0;
+ retry:
++ if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
++ rv = -ENODEV;
++ goto err;
++ }
+ i++;
+- rv = wait_event_interruptible(desc->wait,
+- test_bit(WDM_READ, &desc->flags));
++ if (file->f_flags & O_NONBLOCK) {
++ if (!test_bit(WDM_READ, &desc->flags)) {
++ rv = cntr ? cntr : -EAGAIN;
++ goto err;
++ }
++ rv = 0;
++ } else {
++ rv = wait_event_interruptible(desc->wait,
++ test_bit(WDM_READ, &desc->flags));
++ }
+
++ /* may have happened while we slept */
+ if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+ rv = -ENODEV;
+ goto err;
+@@ -448,7 +466,7 @@ retry:
+
+ err:
+ mutex_unlock(&desc->rlock);
+- if (rv < 0)
++ if (rv < 0 && rv != -EAGAIN)
+ dev_err(&desc->intf->dev, "wdm_read: exit error\n");
+ return rv;
+ }
+diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
+index b09a527..21b3719 100644
+--- a/drivers/usb/class/usbtmc.c
++++ b/drivers/usb/class/usbtmc.c
+@@ -367,13 +367,13 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
+ {
+ struct usbtmc_device_data *data;
+ struct device *dev;
+- unsigned long int n_characters;
++ u32 n_characters;
+ u8 *buffer;
+ int actual;
+- int done;
+- int remaining;
++ size_t done;
++ size_t remaining;
+ int retval;
+- int this_part;
++ size_t this_part;
+
+ /* Get pointer to private data structure */
+ data = filp->private_data;
+@@ -455,6 +455,18 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
+ (buffer[6] << 16) +
+ (buffer[7] << 24);
+
++ /* Ensure the instrument doesn't lie about it */
++ if(n_characters > actual - 12) {
++ dev_err(dev, "Device lies about message size: %zu > %zu\n", n_characters, actual - 12);
++ n_characters = actual - 12;
++ }
++
++ /* Ensure the instrument doesn't send more back than requested */
++ if(n_characters > this_part) {
++ dev_err(dev, "Device returns more than requested: %zu > %zu\n", done + n_characters, done + this_part);
++ n_characters = this_part;
++ }
++
+ /* Copy buffer to user space */
+ if (copy_to_user(buf + done, &buffer[12], n_characters)) {
+ /* There must have been an addressing problem */
+@@ -465,6 +477,8 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
+ done += n_characters;
+ if (n_characters < USBTMC_SIZE_IOBUFFER)
+ remaining = 0;
++ else
++ remaining -= n_characters;
+ }
+
+ /* Update file position value */
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
+index a16c538..0d3af6a 100644
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -105,7 +105,7 @@ static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
+ ep->ss_ep_comp->extralen = i;
+ buffer += i;
+ size -= i;
+- retval = buffer - buffer_start + i;
++ retval = buffer - buffer_start;
+ if (num_skipped > 0)
+ dev_dbg(ddev, "skipped %d descriptor%s after %s\n",
+ num_skipped, plural(num_skipped),
+diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
+index a949259..5b22a4d 100644
+--- a/drivers/usb/host/sl811-hcd.c
++++ b/drivers/usb/host/sl811-hcd.c
+@@ -719,8 +719,12 @@ retry:
+ /* port status seems weird until after reset, so
+ * force the reset and make khubd clean up later.
+ */
+- sl811->port1 |= (1 << USB_PORT_FEAT_C_CONNECTION)
+- | (1 << USB_PORT_FEAT_CONNECTION);
++ if (sl811->stat_insrmv & 1)
++ sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
++ else
++ sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION);
++
++ sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION;
+
+ } else if (irqstat & SL11H_INTMASK_RD) {
+ if (sl811->port1 & (1 << USB_PORT_FEAT_SUSPEND)) {
+diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
+index 705e343..33128d5 100644
+--- a/drivers/usb/host/xhci-dbg.c
++++ b/drivers/usb/host/xhci-dbg.c
+@@ -413,7 +413,8 @@ void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
+ int i;
+
+ struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
+- dma_addr_t dma = ctx->dma + ((unsigned long)slot_ctx - (unsigned long)ctx);
++ dma_addr_t dma = ctx->dma +
++ ((unsigned long)slot_ctx - (unsigned long)ctx->bytes);
+ int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
+
+ xhci_dbg(xhci, "Slot Context:\n");
+@@ -459,7 +460,7 @@ void xhci_dbg_ep_ctx(struct xhci_hcd *xhci,
+ for (i = 0; i < last_ep_ctx; ++i) {
+ struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i);
+ dma_addr_t dma = ctx->dma +
+- ((unsigned long)ep_ctx - (unsigned long)ctx);
++ ((unsigned long)ep_ctx - (unsigned long)ctx->bytes);
+
+ xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
+ xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
+diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
+index 816c39c..e478a63 100644
+--- a/drivers/usb/host/xhci-hcd.c
++++ b/drivers/usb/host/xhci-hcd.c
+@@ -22,12 +22,18 @@
+
+ #include <linux/irq.h>
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+
+ #include "xhci.h"
+
+ #define DRIVER_AUTHOR "Sarah Sharp"
+ #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
+
++/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
++static int link_quirk;
++module_param(link_quirk, int, S_IRUGO | S_IWUSR);
++MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
++
+ /* TODO: copied from ehci-hcd.c - can this be refactored? */
+ /*
+ * handshake - spin reading hc until handshake completes or fails
+@@ -214,6 +220,12 @@ int xhci_init(struct usb_hcd *hcd)
+
+ xhci_dbg(xhci, "xhci_init\n");
+ spin_lock_init(&xhci->lock);
++ if (link_quirk) {
++ xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n");
++ xhci->quirks |= XHCI_LINK_TRB_QUIRK;
++ } else {
++ xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
++ }
+ retval = xhci_mem_init(xhci, GFP_KERNEL);
+ xhci_dbg(xhci, "Finished xhci_init\n");
+
+@@ -555,13 +567,22 @@ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc)
+ return 1 << (xhci_get_endpoint_index(desc) + 1);
+ }
+
++/* Find the flag for this endpoint (for use in the control context). Use the
++ * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
++ * bit 1, etc.
++ */
++unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index)
++{
++ return 1 << (ep_index + 1);
++}
++
+ /* Compute the last valid endpoint context index. Basically, this is the
+ * endpoint index plus one. For slot contexts with more than valid endpoint,
+ * we find the most significant bit set in the added contexts flags.
+ * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000
+ * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one.
+ */
+-static inline unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
++unsigned int xhci_last_valid_endpoint(u32 added_ctxs)
+ {
+ return fls(added_ctxs) - 1;
+ }
+@@ -589,6 +610,70 @@ int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
+ return 1;
+ }
+
++static int xhci_configure_endpoint(struct xhci_hcd *xhci,
++ struct usb_device *udev, struct xhci_virt_device *virt_dev,
++ bool ctx_change);
++
++/*
++ * Full speed devices may have a max packet size greater than 8 bytes, but the
++ * USB core doesn't know that until it reads the first 8 bytes of the
++ * descriptor. If the usb_device's max packet size changes after that point,
++ * we need to issue an evaluate context command and wait on it.
++ */
++static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
++ unsigned int ep_index, struct urb *urb)
++{
++ struct xhci_container_ctx *in_ctx;
++ struct xhci_container_ctx *out_ctx;
++ struct xhci_input_control_ctx *ctrl_ctx;
++ struct xhci_ep_ctx *ep_ctx;
++ int max_packet_size;
++ int hw_max_packet_size;
++ int ret = 0;
++
++ out_ctx = xhci->devs[slot_id]->out_ctx;
++ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
++ hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2);
++ max_packet_size = urb->dev->ep0.desc.wMaxPacketSize;
++ if (hw_max_packet_size != max_packet_size) {
++ xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n");
++ xhci_dbg(xhci, "Max packet size in usb_device = %d\n",
++ max_packet_size);
++ xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n",
++ hw_max_packet_size);
++ xhci_dbg(xhci, "Issuing evaluate context command.\n");
++
++ /* Set up the modified control endpoint 0 */
++ xhci_endpoint_copy(xhci, xhci->devs[slot_id], ep_index);
++ in_ctx = xhci->devs[slot_id]->in_ctx;
++ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
++ ep_ctx->ep_info2 &= ~MAX_PACKET_MASK;
++ ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size);
++
++ /* Set up the input context flags for the command */
++ /* FIXME: This won't work if a non-default control endpoint
++ * changes max packet sizes.
++ */
++ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
++ ctrl_ctx->add_flags = EP0_FLAG;
++ ctrl_ctx->drop_flags = 0;
++
++ xhci_dbg(xhci, "Slot %d input context\n", slot_id);
++ xhci_dbg_ctx(xhci, in_ctx, ep_index);
++ xhci_dbg(xhci, "Slot %d output context\n", slot_id);
++ xhci_dbg_ctx(xhci, out_ctx, ep_index);
++
++ ret = xhci_configure_endpoint(xhci, urb->dev,
++ xhci->devs[slot_id], true);
++
++ /* Clean up the input context for later use by bandwidth
++ * functions.
++ */
++ ctrl_ctx->add_flags = SLOT_FLAG;
++ }
++ return ret;
++}
++
+ /*
+ * non-error returns are a promise to giveback() the urb later
+ * we drop ownership so next owner (or urb unlink) can get it
+@@ -600,13 +685,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
+ int ret = 0;
+ unsigned int slot_id, ep_index;
+
++
+ if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
+ return -EINVAL;
+
+ slot_id = urb->dev->slot_id;
+ ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+
+- spin_lock_irqsave(&xhci->lock, flags);
+ if (!xhci->devs || !xhci->devs[slot_id]) {
+ if (!in_interrupt())
+ dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
+@@ -619,19 +704,38 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
+ ret = -ESHUTDOWN;
+ goto exit;
+ }
+- if (usb_endpoint_xfer_control(&urb->ep->desc))
++ if (usb_endpoint_xfer_control(&urb->ep->desc)) {
++ /* Check to see if the max packet size for the default control
++ * endpoint changed during FS device enumeration
++ */
++ if (urb->dev->speed == USB_SPEED_FULL) {
++ ret = xhci_check_maxpacket(xhci, slot_id,
++ ep_index, urb);
++ if (ret < 0)
++ return ret;
++ }
++
+ /* We have a spinlock and interrupts disabled, so we must pass
+ * atomic context to this function, which may allocate memory.
+ */
++ spin_lock_irqsave(&xhci->lock, flags);
+ ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
+- else if (usb_endpoint_xfer_bulk(&urb->ep->desc))
++ spin_unlock_irqrestore(&xhci->lock, flags);
++ } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
++ spin_lock_irqsave(&xhci->lock, flags);
+ ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
+- else
++ spin_unlock_irqrestore(&xhci->lock, flags);
++ } else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
++ spin_lock_irqsave(&xhci->lock, flags);
++ ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
++ slot_id, ep_index);
++ spin_unlock_irqrestore(&xhci->lock, flags);
++ } else {
+ ret = -EINVAL;
++ }
+ exit:
+- spin_unlock_irqrestore(&xhci->lock, flags);
+ return ret;
+ }
+
+@@ -930,6 +1034,122 @@ static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *vir
+ }
+ }
+
++static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
++ struct usb_device *udev, struct xhci_virt_device *virt_dev)
++{
++ int ret;
++
++ switch (virt_dev->cmd_status) {
++ case COMP_ENOMEM:
++ dev_warn(&udev->dev, "Not enough host controller resources "
++ "for new device state.\n");
++ ret = -ENOMEM;
++ /* FIXME: can we allocate more resources for the HC? */
++ break;
++ case COMP_BW_ERR:
++ dev_warn(&udev->dev, "Not enough bandwidth "
++ "for new device state.\n");
++ ret = -ENOSPC;
++ /* FIXME: can we go back to the old state? */
++ break;
++ case COMP_TRB_ERR:
++ /* the HCD set up something wrong */
++ dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, "
++ "add flag = 1, "
++ "and endpoint is not disabled.\n");
++ ret = -EINVAL;
++ break;
++ case COMP_SUCCESS:
++ dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
++ ret = 0;
++ break;
++ default:
++ xhci_err(xhci, "ERROR: unexpected command completion "
++ "code 0x%x.\n", virt_dev->cmd_status);
++ ret = -EINVAL;
++ break;
++ }
++ return ret;
++}
++
++static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
++ struct usb_device *udev, struct xhci_virt_device *virt_dev)
++{
++ int ret;
++
++ switch (virt_dev->cmd_status) {
++ case COMP_EINVAL:
++ dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "
++ "context command.\n");
++ ret = -EINVAL;
++ break;
++ case COMP_EBADSLT:
++ dev_warn(&udev->dev, "WARN: slot not enabled for"
++ "evaluate context command.\n");
++ case COMP_CTX_STATE:
++ dev_warn(&udev->dev, "WARN: invalid context state for "
++ "evaluate context command.\n");
++ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
++ ret = -EINVAL;
++ break;
++ case COMP_SUCCESS:
++ dev_dbg(&udev->dev, "Successful evaluate context command\n");
++ ret = 0;
++ break;
++ default:
++ xhci_err(xhci, "ERROR: unexpected command completion "
++ "code 0x%x.\n", virt_dev->cmd_status);
++ ret = -EINVAL;
++ break;
++ }
++ return ret;
++}
++
++/* Issue a configure endpoint command or evaluate context command
++ * and wait for it to finish.
++ */
++static int xhci_configure_endpoint(struct xhci_hcd *xhci,
++ struct usb_device *udev, struct xhci_virt_device *virt_dev,
++ bool ctx_change)
++{
++ int ret;
++ int timeleft;
++ unsigned long flags;
++
++ spin_lock_irqsave(&xhci->lock, flags);
++ if (!ctx_change)
++ ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma,
++ udev->slot_id);
++ else
++ ret = xhci_queue_evaluate_context(xhci, virt_dev->in_ctx->dma,
++ udev->slot_id);
++ if (ret < 0) {
++ spin_unlock_irqrestore(&xhci->lock, flags);
++ xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
++ return -ENOMEM;
++ }
++ xhci_ring_cmd_db(xhci);
++ spin_unlock_irqrestore(&xhci->lock, flags);
++
++ /* Wait for the configure endpoint command to complete */
++ timeleft = wait_for_completion_interruptible_timeout(
++ &virt_dev->cmd_completion,
++ USB_CTRL_SET_TIMEOUT);
++ if (timeleft <= 0) {
++ xhci_warn(xhci, "%s while waiting for %s command\n",
++ timeleft == 0 ? "Timeout" : "Signal",
++ ctx_change == 0 ?
++ "configure endpoint" :
++ "evaluate context");
++ /* FIXME cancel the configure endpoint command */
++ return -ETIME;
++ }
++
++ if (!ctx_change)
++ return xhci_configure_endpoint_result(xhci, udev, virt_dev);
++ return xhci_evaluate_context_result(xhci, udev, virt_dev);
++}
++
+ /* Called after one or more calls to xhci_add_endpoint() or
+ * xhci_drop_endpoint(). If this call fails, the USB core is expected
+ * to call xhci_reset_bandwidth().
+@@ -944,8 +1164,6 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+ {
+ int i;
+ int ret = 0;
+- int timeleft;
+- unsigned long flags;
+ struct xhci_hcd *xhci;
+ struct xhci_virt_device *virt_dev;
+ struct xhci_input_control_ctx *ctrl_ctx;
+@@ -975,56 +1193,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+ xhci_dbg_ctx(xhci, virt_dev->in_ctx,
+ LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
+
+- spin_lock_irqsave(&xhci->lock, flags);
+- ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma,
+- udev->slot_id);
+- if (ret < 0) {
+- spin_unlock_irqrestore(&xhci->lock, flags);
+- xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
+- return -ENOMEM;
+- }
+- xhci_ring_cmd_db(xhci);
+- spin_unlock_irqrestore(&xhci->lock, flags);
+-
+- /* Wait for the configure endpoint command to complete */
+- timeleft = wait_for_completion_interruptible_timeout(
+- &virt_dev->cmd_completion,
+- USB_CTRL_SET_TIMEOUT);
+- if (timeleft <= 0) {
+- xhci_warn(xhci, "%s while waiting for configure endpoint command\n",
+- timeleft == 0 ? "Timeout" : "Signal");
+- /* FIXME cancel the configure endpoint command */
+- return -ETIME;
+- }
+-
+- switch (virt_dev->cmd_status) {
+- case COMP_ENOMEM:
+- dev_warn(&udev->dev, "Not enough host controller resources "
+- "for new device state.\n");
+- ret = -ENOMEM;
+- /* FIXME: can we allocate more resources for the HC? */
+- break;
+- case COMP_BW_ERR:
+- dev_warn(&udev->dev, "Not enough bandwidth "
+- "for new device state.\n");
+- ret = -ENOSPC;
+- /* FIXME: can we go back to the old state? */
+- break;
+- case COMP_TRB_ERR:
+- /* the HCD set up something wrong */
+- dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, add flag = 1, "
+- "and endpoint is not disabled.\n");
+- ret = -EINVAL;
+- break;
+- case COMP_SUCCESS:
+- dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
+- break;
+- default:
+- xhci_err(xhci, "ERROR: unexpected command completion "
+- "code 0x%x.\n", virt_dev->cmd_status);
+- ret = -EINVAL;
+- break;
+- }
++ ret = xhci_configure_endpoint(xhci, udev, virt_dev, false);
+ if (ret) {
+ /* Callee should call reset_bandwidth() */
+ return ret;
+@@ -1075,6 +1244,75 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
+ xhci_zero_in_ctx(xhci, virt_dev);
+ }
+
++void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
++ unsigned int slot_id, unsigned int ep_index,
++ struct xhci_dequeue_state *deq_state)
++{
++ struct xhci_container_ctx *in_ctx;
++ struct xhci_input_control_ctx *ctrl_ctx;
++ struct xhci_ep_ctx *ep_ctx;
++ u32 added_ctxs;
++ dma_addr_t addr;
++
++ xhci_endpoint_copy(xhci, xhci->devs[slot_id], ep_index);
++ in_ctx = xhci->devs[slot_id]->in_ctx;
++ ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
++ addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg,
++ deq_state->new_deq_ptr);
++ if (addr == 0) {
++ xhci_warn(xhci, "WARN Cannot submit config ep after "
++ "reset ep command\n");
++ xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
++ deq_state->new_deq_seg,
++ deq_state->new_deq_ptr);
++ return;
++ }
++ ep_ctx->deq = addr | deq_state->new_cycle_state;
++
++ xhci_slot_copy(xhci, xhci->devs[slot_id]);
++
++ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
++ added_ctxs = xhci_get_endpoint_flag_from_index(ep_index);
++ ctrl_ctx->add_flags = added_ctxs | SLOT_FLAG;
++ ctrl_ctx->drop_flags = added_ctxs;
++
++ xhci_dbg(xhci, "Slot ID %d Input Context:\n", slot_id);
++ xhci_dbg_ctx(xhci, in_ctx, ep_index);
++}
++
++void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
++ struct usb_device *udev,
++ unsigned int ep_index, struct xhci_ring *ep_ring)
++{
++ struct xhci_dequeue_state deq_state;
++
++ xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
++ /* We need to move the HW's dequeue pointer past this TD,
++ * or it will attempt to resend it on the next doorbell ring.
++ */
++ xhci_find_new_dequeue_state(xhci, udev->slot_id,
++ ep_index, ep_ring->stopped_td,
++ &deq_state);
++
++ /* HW with the reset endpoint quirk will use the saved dequeue state to
++ * issue a configure endpoint command later.
++ */
++ if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
++ xhci_dbg(xhci, "Queueing new dequeue state\n");
++ xhci_queue_new_dequeue_state(xhci, ep_ring,
++ udev->slot_id,
++ ep_index, &deq_state);
++ } else {
++ /* Better hope no one uses the input context between now and the
++ * reset endpoint completion!
++ */
++ xhci_dbg(xhci, "Setting up input context for "
++ "configure endpoint command\n");
++ xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
++ ep_index, &deq_state);
++ }
++}
++
+ /* Deal with stalled endpoints. The core should have sent the control message
+ * to clear the halt condition. However, we need to make the xHCI hardware
+ * reset its sequence number, since a device will expect a sequence number of
+@@ -1089,7 +1327,6 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
+ unsigned int ep_index;
+ unsigned long flags;
+ int ret;
+- struct xhci_dequeue_state deq_state;
+ struct xhci_ring *ep_ring;
+
+ xhci = hcd_to_xhci(hcd);
+@@ -1106,6 +1343,10 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
+ ep->desc.bEndpointAddress);
+ return;
+ }
++ if (usb_endpoint_xfer_control(&ep->desc)) {
++ xhci_dbg(xhci, "Control endpoint stall already handled.\n");
++ return;
++ }
+
+ xhci_dbg(xhci, "Queueing reset endpoint command\n");
+ spin_lock_irqsave(&xhci->lock, flags);
+@@ -1116,16 +1357,7 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
+ * command. Better hope that last command worked!
+ */
+ if (!ret) {
+- xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
+- /* We need to move the HW's dequeue pointer past this TD,
+- * or it will attempt to resend it on the next doorbell ring.
+- */
+- xhci_find_new_dequeue_state(xhci, udev->slot_id,
+- ep_index, ep_ring->stopped_td, &deq_state);
+- xhci_dbg(xhci, "Queueing new dequeue state\n");
+- xhci_queue_new_dequeue_state(xhci, ep_ring,
+- udev->slot_id,
+- ep_index, &deq_state);
++ xhci_cleanup_stalled_ring(xhci, udev, ep_index, ep_ring);
+ kfree(ep_ring->stopped_td);
+ xhci_ring_cmd_db(xhci);
+ }
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index e6b9a1c..55920b3 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -94,6 +94,9 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
+ val = prev->trbs[TRBS_PER_SEGMENT-1].link.control;
+ val &= ~TRB_TYPE_BITMASK;
+ val |= TRB_TYPE(TRB_LINK);
++ /* Always set the chain bit with 0.95 hardware */
++ if (xhci_link_trb_quirk(xhci))
++ val |= TRB_CHAIN;
+ prev->trbs[TRBS_PER_SEGMENT-1].link.control = val;
+ }
+ xhci_dbg(xhci, "Linking segment 0x%llx to segment 0x%llx (DMA)\n",
+@@ -398,15 +401,28 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
+ /* Step 5 */
+ ep0_ctx->ep_info2 = EP_TYPE(CTRL_EP);
+ /*
+- * See section 4.3 bullet 6:
+- * The default Max Packet size for ep0 is "8 bytes for a USB2
+- * LS/FS/HS device or 512 bytes for a USB3 SS device"
+ * XXX: Not sure about wireless USB devices.
+ */
+- if (udev->speed == USB_SPEED_SUPER)
++ switch (udev->speed) {
++ case USB_SPEED_SUPER:
+ ep0_ctx->ep_info2 |= MAX_PACKET(512);
+- else
++ break;
++ case USB_SPEED_HIGH:
++ /* USB core guesses at a 64-byte max packet first for FS devices */
++ case USB_SPEED_FULL:
++ ep0_ctx->ep_info2 |= MAX_PACKET(64);
++ break;
++ case USB_SPEED_LOW:
+ ep0_ctx->ep_info2 |= MAX_PACKET(8);
++ break;
++ case USB_SPEED_VARIABLE:
++ xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
++ return -EINVAL;
++ break;
++ default:
++ /* New speed? */
++ BUG();
++ }
+ /* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
+ ep0_ctx->ep_info2 |= MAX_BURST(0);
+ ep0_ctx->ep_info2 |= ERROR_COUNT(3);
+@@ -598,6 +614,44 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
+ */
+ }
+
++/* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy.
++ * Useful when you want to change one particular aspect of the endpoint and then
++ * issue a configure endpoint command.
++ */
++void xhci_endpoint_copy(struct xhci_hcd *xhci,
++ struct xhci_virt_device *vdev, unsigned int ep_index)
++{
++ struct xhci_ep_ctx *out_ep_ctx;
++ struct xhci_ep_ctx *in_ep_ctx;
++
++ out_ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, ep_index);
++ in_ep_ctx = xhci_get_ep_ctx(xhci, vdev->in_ctx, ep_index);
++
++ in_ep_ctx->ep_info = out_ep_ctx->ep_info;
++ in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2;
++ in_ep_ctx->deq = out_ep_ctx->deq;
++ in_ep_ctx->tx_info = out_ep_ctx->tx_info;
++}
++
++/* Copy output xhci_slot_ctx to the input xhci_slot_ctx.
++ * Useful when you want to change one particular aspect of the endpoint and then
++ * issue a configure endpoint command. Only the context entries field matters,
++ * but we'll copy the whole thing anyway.
++ */
++void xhci_slot_copy(struct xhci_hcd *xhci, struct xhci_virt_device *vdev)
++{
++ struct xhci_slot_ctx *in_slot_ctx;
++ struct xhci_slot_ctx *out_slot_ctx;
++
++ in_slot_ctx = xhci_get_slot_ctx(xhci, vdev->in_ctx);
++ out_slot_ctx = xhci_get_slot_ctx(xhci, vdev->out_ctx);
++
++ in_slot_ctx->dev_info = out_slot_ctx->dev_info;
++ in_slot_ctx->dev_info2 = out_slot_ctx->dev_info2;
++ in_slot_ctx->tt_info = out_slot_ctx->tt_info;
++ in_slot_ctx->dev_state = out_slot_ctx->dev_state;
++}
++
+ /* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
+ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
+ {
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 592fe7e..8fb308d 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -24,6 +24,10 @@
+
+ #include "xhci.h"
+
++/* Device for a quirk */
++#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
++#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
++
+ static const char hcd_name[] = "xhci_hcd";
+
+ /* called after powerup, by probe or system-pm "wakeup" */
+@@ -62,6 +66,15 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
+ xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+ xhci_print_registers(xhci);
+
++ /* Look for vendor-specific quirks */
++ if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
++ pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
++ pdev->revision == 0x0) {
++ xhci->quirks |= XHCI_RESET_EP_QUIRK;
++ xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
++ " endpoint cmd after reset endpoint\n");
++ }
++
+ /* Make sure the HC is halted. */
+ retval = xhci_halt(xhci);
+ if (retval)
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index aa88a06..ff5e6bc 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -172,8 +172,9 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
+ * have their chain bit cleared (so that each Link TRB is a separate TD).
+ *
+ * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit
+- * set, but other sections talk about dealing with the chain bit set.
+- * Assume section 6.4.4.1 is wrong, and the chain bit can be set in a Link TRB.
++ * set, but other sections talk about dealing with the chain bit set. This was
++ * fixed in the 0.96 specification errata, but we have to assume that all 0.95
++ * xHCI hardware can't handle the chain bit being cleared on a link TRB.
+ */
+ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer)
+ {
+@@ -191,8 +192,14 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
+ while (last_trb(xhci, ring, ring->enq_seg, next)) {
+ if (!consumer) {
+ if (ring != xhci->event_ring) {
+- next->link.control &= ~TRB_CHAIN;
+- next->link.control |= chain;
++ /* If we're not dealing with 0.95 hardware,
++ * carry over the chain bit of the previous TRB
++ * (which may mean the chain bit is cleared).
++ */
++ if (!xhci_link_trb_quirk(xhci)) {
++ next->link.control &= ~TRB_CHAIN;
++ next->link.control |= chain;
++ }
+ /* Give this link TRB to the hardware */
+ wmb();
+ if (next->link.control & TRB_CYCLE)
+@@ -462,7 +469,6 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
+ * ring running.
+ */
+ ep_ring->state |= SET_DEQ_PENDING;
+- xhci_ring_cmd_db(xhci);
+ }
+
+ /*
+@@ -531,6 +537,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
+ if (deq_state.new_deq_ptr && deq_state.new_deq_seg) {
+ xhci_queue_new_dequeue_state(xhci, ep_ring,
+ slot_id, ep_index, &deq_state);
++ xhci_ring_cmd_db(xhci);
+ } else {
+ /* Otherwise just ring the doorbell to restart the ring */
+ ring_ep_doorbell(xhci, slot_id, ep_index);
+@@ -644,18 +651,31 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,
+ {
+ int slot_id;
+ unsigned int ep_index;
++ struct xhci_ring *ep_ring;
+
+ slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
+ ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
++ ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
+ /* This command will only fail if the endpoint wasn't halted,
+ * but we don't care.
+ */
+ xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n",
+ (unsigned int) GET_COMP_CODE(event->status));
+
+- /* Clear our internal halted state and restart the ring */
+- xhci->devs[slot_id]->ep_rings[ep_index]->state &= ~EP_HALTED;
+- ring_ep_doorbell(xhci, slot_id, ep_index);
++ /* HW with the reset endpoint quirk needs to have a configure endpoint
++ * command complete before the endpoint can be used. Queue that here
++ * because the HW can't handle two commands being queued in a row.
++ */
++ if (xhci->quirks & XHCI_RESET_EP_QUIRK) {
++ xhci_dbg(xhci, "Queueing configure endpoint command\n");
++ xhci_queue_configure_endpoint(xhci,
++ xhci->devs[slot_id]->in_ctx->dma, slot_id);
++ xhci_ring_cmd_db(xhci);
++ } else {
++ /* Clear our internal halted state and restart the ring */
++ ep_ring->state &= ~EP_HALTED;
++ ring_ep_doorbell(xhci, slot_id, ep_index);
++ }
+ }
+
+ static void handle_cmd_completion(struct xhci_hcd *xhci,
+@@ -664,6 +684,10 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
+ int slot_id = TRB_TO_SLOT_ID(event->flags);
+ u64 cmd_dma;
+ dma_addr_t cmd_dequeue_dma;
++ struct xhci_input_control_ctx *ctrl_ctx;
++ unsigned int ep_index;
++ struct xhci_ring *ep_ring;
++ unsigned int ep_state;
+
+ cmd_dma = event->cmd_trb;
+ cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
+@@ -691,6 +715,41 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
+ xhci_free_virt_device(xhci, slot_id);
+ break;
+ case TRB_TYPE(TRB_CONFIG_EP):
++ /*
++ * Configure endpoint commands can come from the USB core
++ * configuration or alt setting changes, or because the HW
++ * needed an extra configure endpoint command after a reset
++ * endpoint command. In the latter case, the xHCI driver is
++ * not waiting on the configure endpoint command.
++ */
++ ctrl_ctx = xhci_get_input_control_ctx(xhci,
++ xhci->devs[slot_id]->in_ctx);
++ /* Input ctx add_flags are the endpoint index plus one */
++ ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1;
++ ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
++ if (!ep_ring) {
++ /* This must have been an initial configure endpoint */
++ xhci->devs[slot_id]->cmd_status =
++ GET_COMP_CODE(event->status);
++ complete(&xhci->devs[slot_id]->cmd_completion);
++ break;
++ }
++ ep_state = ep_ring->state;
++ xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, "
++ "state = %d\n", ep_index, ep_state);
++ if (xhci->quirks & XHCI_RESET_EP_QUIRK &&
++ ep_state & EP_HALTED) {
++ /* Clear our internal halted state and restart ring */
++ xhci->devs[slot_id]->ep_rings[ep_index]->state &=
++ ~EP_HALTED;
++ ring_ep_doorbell(xhci, slot_id, ep_index);
++ } else {
++ xhci->devs[slot_id]->cmd_status =
++ GET_COMP_CODE(event->status);
++ complete(&xhci->devs[slot_id]->cmd_completion);
++ }
++ break;
++ case TRB_TYPE(TRB_EVAL_CONTEXT):
+ xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status);
+ complete(&xhci->devs[slot_id]->cmd_completion);
+ break;
+@@ -806,6 +865,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ {
+ struct xhci_virt_device *xdev;
+ struct xhci_ring *ep_ring;
++ unsigned int slot_id;
+ int ep_index;
+ struct xhci_td *td = 0;
+ dma_addr_t event_dma;
+@@ -814,9 +874,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ struct urb *urb = 0;
+ int status = -EINPROGRESS;
+ struct xhci_ep_ctx *ep_ctx;
++ u32 trb_comp_code;
+
+ xhci_dbg(xhci, "In %s\n", __func__);
+- xdev = xhci->devs[TRB_TO_SLOT_ID(event->flags)];
++ slot_id = TRB_TO_SLOT_ID(event->flags);
++ xdev = xhci->devs[slot_id];
+ if (!xdev) {
+ xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n");
+ return -ENODEV;
+@@ -870,7 +932,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ (unsigned int) event->flags);
+
+ /* Look for common error cases */
+- switch (GET_COMP_CODE(event->transfer_len)) {
++ trb_comp_code = GET_COMP_CODE(event->transfer_len);
++ switch (trb_comp_code) {
+ /* Skip codes that require special handling depending on
+ * transfer type
+ */
+@@ -913,7 +976,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ /* Was this a control transfer? */
+ if (usb_endpoint_xfer_control(&td->urb->ep->desc)) {
+ xhci_debug_trb(xhci, xhci->event_ring->dequeue);
+- switch (GET_COMP_CODE(event->transfer_len)) {
++ switch (trb_comp_code) {
+ case COMP_SUCCESS:
+ if (event_trb == ep_ring->dequeue) {
+ xhci_warn(xhci, "WARN: Success on ctrl setup TRB without IOC set??\n");
+@@ -928,8 +991,39 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ break;
+ case COMP_SHORT_TX:
+ xhci_warn(xhci, "WARN: short transfer on control ep\n");
+- status = -EREMOTEIO;
++ if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
++ status = -EREMOTEIO;
++ else
++ status = 0;
+ break;
++ case COMP_BABBLE:
++ /* The 0.96 spec says a babbling control endpoint
++ * is not halted. The 0.96 spec says it is. Some HW
++ * claims to be 0.95 compliant, but it halts the control
++ * endpoint anyway. Check if a babble halted the
++ * endpoint.
++ */
++ if (ep_ctx->ep_info != EP_STATE_HALTED)
++ break;
++ /* else fall through */
++ case COMP_STALL:
++ /* Did we transfer part of the data (middle) phase? */
++ if (event_trb != ep_ring->dequeue &&
++ event_trb != td->last_trb)
++ td->urb->actual_length =
++ td->urb->transfer_buffer_length
++ - TRB_LEN(event->transfer_len);
++ else
++ td->urb->actual_length = 0;
++
++ ep_ring->stopped_td = td;
++ ep_ring->stopped_trb = event_trb;
++ xhci_queue_reset_ep(xhci, slot_id, ep_index);
++ xhci_cleanup_stalled_ring(xhci,
++ td->urb->dev,
++ ep_index, ep_ring);
++ xhci_ring_cmd_db(xhci);
++ goto td_cleanup;
+ default:
+ /* Others already handled above */
+ break;
+@@ -943,7 +1037,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ if (event_trb == td->last_trb) {
+ if (td->urb->actual_length != 0) {
+ /* Don't overwrite a previously set error code */
+- if (status == -EINPROGRESS || status == 0)
++ if ((status == -EINPROGRESS ||
++ status == 0) &&
++ (td->urb->transfer_flags
++ & URB_SHORT_NOT_OK))
+ /* Did we already see a short data stage? */
+ status = -EREMOTEIO;
+ } else {
+@@ -952,7 +1049,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ }
+ } else {
+ /* Maybe the event was for the data stage? */
+- if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) {
++ if (trb_comp_code != COMP_STOP_INVAL) {
+ /* We didn't stop on a link TRB in the middle */
+ td->urb->actual_length =
+ td->urb->transfer_buffer_length -
+@@ -964,7 +1061,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ }
+ }
+ } else {
+- switch (GET_COMP_CODE(event->transfer_len)) {
++ switch (trb_comp_code) {
+ case COMP_SUCCESS:
+ /* Double check that the HW transferred everything. */
+ if (event_trb != td->last_trb) {
+@@ -975,7 +1072,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ else
+ status = 0;
+ } else {
+- xhci_dbg(xhci, "Successful bulk transfer!\n");
++ if (usb_endpoint_xfer_bulk(&td->urb->ep->desc))
++ xhci_dbg(xhci, "Successful bulk "
++ "transfer!\n");
++ else
++ xhci_dbg(xhci, "Successful interrupt "
++ "transfer!\n");
+ status = 0;
+ }
+ break;
+@@ -1001,11 +1103,17 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ td->urb->actual_length =
+ td->urb->transfer_buffer_length -
+ TRB_LEN(event->transfer_len);
+- if (td->urb->actual_length < 0) {
++ if (td->urb->transfer_buffer_length <
++ td->urb->actual_length) {
+ xhci_warn(xhci, "HC gave bad length "
+ "of %d bytes left\n",
+ TRB_LEN(event->transfer_len));
+ td->urb->actual_length = 0;
++ if (td->urb->transfer_flags &
++ URB_SHORT_NOT_OK)
++ status = -EREMOTEIO;
++ else
++ status = 0;
+ }
+ /* Don't overwrite a previously set error code */
+ if (status == -EINPROGRESS) {
+@@ -1041,14 +1149,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ /* If the ring didn't stop on a Link or No-op TRB, add
+ * in the actual bytes transferred from the Normal TRB
+ */
+- if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL)
++ if (trb_comp_code != COMP_STOP_INVAL)
+ td->urb->actual_length +=
+ TRB_LEN(cur_trb->generic.field[2]) -
+ TRB_LEN(event->transfer_len);
+ }
+ }
+- if (GET_COMP_CODE(event->transfer_len) == COMP_STOP_INVAL ||
+- GET_COMP_CODE(event->transfer_len) == COMP_STOP) {
++ if (trb_comp_code == COMP_STOP_INVAL ||
++ trb_comp_code == COMP_STOP) {
+ /* The Endpoint Stop Command completion will take care of any
+ * stopped TDs. A stopped TD may be restarted, so don't update
+ * the ring dequeue pointer or take this TD off any lists yet.
+@@ -1056,7 +1164,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ ep_ring->stopped_td = td;
+ ep_ring->stopped_trb = event_trb;
+ } else {
+- if (GET_COMP_CODE(event->transfer_len) == COMP_STALL) {
++ if (trb_comp_code == COMP_STALL ||
++ trb_comp_code == COMP_BABBLE) {
+ /* The transfer is completed from the driver's
+ * perspective, but we need to issue a set dequeue
+ * command for this stalled endpoint to move the dequeue
+@@ -1072,16 +1181,41 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ inc_deq(xhci, ep_ring, false);
+ }
+
++td_cleanup:
+ /* Clean up the endpoint's TD list */
+ urb = td->urb;
++ /* Do one last check of the actual transfer length.
++ * If the host controller said we transferred more data than
++ * the buffer length, urb->actual_length will be a very big
++ * number (since it's unsigned). Play it safe and say we didn't
++ * transfer anything.
++ */
++ if (urb->actual_length > urb->transfer_buffer_length) {
++ xhci_warn(xhci, "URB transfer length is wrong, "
++ "xHC issue? req. len = %u, "
++ "act. len = %u\n",
++ urb->transfer_buffer_length,
++ urb->actual_length);
++ urb->actual_length = 0;
++ if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
++ status = -EREMOTEIO;
++ else
++ status = 0;
++ }
+ list_del(&td->td_list);
+ /* Was this TD slated to be cancelled but completed anyway? */
+ if (!list_empty(&td->cancelled_td_list)) {
+ list_del(&td->cancelled_td_list);
+ ep_ring->cancels_pending--;
+ }
+- /* Leave the TD around for the reset endpoint function to use */
+- if (GET_COMP_CODE(event->transfer_len) != COMP_STALL) {
++ /* Leave the TD around for the reset endpoint function to use
++ * (but only if it's not a control endpoint, since we already
++ * queued the Set TR dequeue pointer command for stalled
++ * control endpoints).
++ */
++ if (usb_endpoint_xfer_control(&urb->ep->desc) ||
++ (trb_comp_code != COMP_STALL &&
++ trb_comp_code != COMP_BABBLE)) {
+ kfree(td);
+ }
+ urb->hcpriv = NULL;
+@@ -1094,7 +1228,7 @@ cleanup:
+ if (urb) {
+ usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb);
+ xhci_dbg(xhci, "Giveback URB %p, len = %d, status = %d\n",
+- urb, td->urb->actual_length, status);
++ urb, urb->actual_length, status);
+ spin_unlock(&xhci->lock);
+ usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status);
+ spin_lock(&xhci->lock);
+@@ -1335,6 +1469,47 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id,
+ ring_ep_doorbell(xhci, slot_id, ep_index);
+ }
+
++/*
++ * xHCI uses normal TRBs for both bulk and interrupt. When the interrupt
++ * endpoint is to be serviced, the xHC will consume (at most) one TD. A TD
++ * (comprised of sg list entries) can take several service intervals to
++ * transmit.
++ */
++int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
++ struct urb *urb, int slot_id, unsigned int ep_index)
++{
++ struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci,
++ xhci->devs[slot_id]->out_ctx, ep_index);
++ int xhci_interval;
++ int ep_interval;
++
++ xhci_interval = EP_INTERVAL_TO_UFRAMES(ep_ctx->ep_info);
++ ep_interval = urb->interval;
++ /* Convert to microframes */
++ if (urb->dev->speed == USB_SPEED_LOW ||
++ urb->dev->speed == USB_SPEED_FULL)
++ ep_interval *= 8;
++ /* FIXME change this to a warning and a suggestion to use the new API
++ * to set the polling interval (once the API is added).
++ */
++ if (xhci_interval != ep_interval) {
++ if (!printk_ratelimit())
++ dev_dbg(&urb->dev->dev, "Driver uses different interval"
++ " (%d microframe%s) than xHCI "
++ "(%d microframe%s)\n",
++ ep_interval,
++ ep_interval == 1 ? "" : "s",
++ xhci_interval,
++ xhci_interval == 1 ? "" : "s");
++ urb->interval = xhci_interval;
++ /* Convert back to frames for LS/FS devices */
++ if (urb->dev->speed == USB_SPEED_LOW ||
++ urb->dev->speed == USB_SPEED_FULL)
++ urb->interval /= 8;
++ }
++ return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
++}
++
+ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
+ struct urb *urb, int slot_id, unsigned int ep_index)
+ {
+@@ -1733,6 +1908,15 @@ int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
+ TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id));
+ }
+
++/* Queue an evaluate context command TRB */
++int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
++ u32 slot_id)
++{
++ return queue_command(xhci, lower_32_bits(in_ctx_ptr),
++ upper_32_bits(in_ctx_ptr), 0,
++ TRB_TYPE(TRB_EVAL_CONTEXT) | SLOT_ID_FOR_TRB(slot_id));
++}
++
+ int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id,
+ unsigned int ep_index)
+ {
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index d31d322..8085841 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -581,6 +581,7 @@ struct xhci_ep_ctx {
+ /* bit 15 is Linear Stream Array */
+ /* Interval - period between requests to an endpoint - 125u increments. */
+ #define EP_INTERVAL(p) ((p & 0xff) << 16)
++#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff))
+
+ /* ep_info2 bitmasks */
+ /*
+@@ -589,6 +590,7 @@ struct xhci_ep_ctx {
+ */
+ #define FORCE_EVENT (0x1)
+ #define ERROR_COUNT(p) (((p) & 0x3) << 1)
++#define CTX_TO_EP_TYPE(p) (((p) >> 3) & 0x7)
+ #define EP_TYPE(p) ((p) << 3)
+ #define ISOC_OUT_EP 1
+ #define BULK_OUT_EP 2
+@@ -601,6 +603,8 @@ struct xhci_ep_ctx {
+ /* bit 7 is Host Initiate Disable - for disabling stream selection */
+ #define MAX_BURST(p) (((p)&0xff) << 8)
+ #define MAX_PACKET(p) (((p)&0xffff) << 16)
++#define MAX_PACKET_MASK (0xffff << 16)
++#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
+
+
+ /**
+@@ -926,6 +930,12 @@ struct xhci_td {
+ union xhci_trb *last_trb;
+ };
+
++struct xhci_dequeue_state {
++ struct xhci_segment *new_deq_seg;
++ union xhci_trb *new_deq_ptr;
++ int new_cycle_state;
++};
++
+ struct xhci_ring {
+ struct xhci_segment *first_seg;
+ union xhci_trb *enqueue;
+@@ -952,12 +962,6 @@ struct xhci_ring {
+ u32 cycle_state;
+ };
+
+-struct xhci_dequeue_state {
+- struct xhci_segment *new_deq_seg;
+- union xhci_trb *new_deq_ptr;
+- int new_cycle_state;
+-};
+-
+ struct xhci_erst_entry {
+ /* 64-bit event ring segment address */
+ u64 seg_addr;
+@@ -1058,6 +1062,9 @@ struct xhci_hcd {
+ int noops_submitted;
+ int noops_handled;
+ int error_bitmask;
++ unsigned int quirks;
++#define XHCI_LINK_TRB_QUIRK (1 << 0)
++#define XHCI_RESET_EP_QUIRK (1 << 1)
+ };
+
+ /* For testing purposes */
+@@ -1136,6 +1143,13 @@ static inline void xhci_write_64(struct xhci_hcd *xhci,
+ writel(val_hi, ptr + 1);
+ }
+
++static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci)
++{
++ u32 temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase);
++ return ((HC_VERSION(temp) == 0x95) &&
++ (xhci->quirks & XHCI_LINK_TRB_QUIRK));
++}
++
+ /* xHCI debugging */
+ void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num);
+ void xhci_print_registers(struct xhci_hcd *xhci);
+@@ -1158,7 +1172,12 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device
+ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
+ unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc);
+ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
++unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
++unsigned int xhci_last_valid_endpoint(u32 added_ctxs);
+ void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep);
++void xhci_endpoint_copy(struct xhci_hcd *xhci,
++ struct xhci_virt_device *vdev, unsigned int ep_index);
++void xhci_slot_copy(struct xhci_hcd *xhci, struct xhci_virt_device *vdev);
+ int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev,
+ struct usb_device *udev, struct usb_host_endpoint *ep,
+ gfp_t mem_flags);
+@@ -1205,8 +1224,12 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
+ int slot_id, unsigned int ep_index);
+ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
+ int slot_id, unsigned int ep_index);
++int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
++ int slot_id, unsigned int ep_index);
+ int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
+ u32 slot_id);
++int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
++ u32 slot_id);
+ int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
+ unsigned int ep_index);
+ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
+@@ -1215,6 +1238,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
+ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
+ struct xhci_ring *ep_ring, unsigned int slot_id,
+ unsigned int ep_index, struct xhci_dequeue_state *deq_state);
++void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
++ struct usb_device *udev,
++ unsigned int ep_index, struct xhci_ring *ep_ring);
++void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
++ unsigned int slot_id, unsigned int ep_index,
++ struct xhci_dequeue_state *deq_state);
+
+ /* xHCI roothub code */
+ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
+diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
+index aec6188..1a50beb 100644
+--- a/drivers/usb/serial/ark3116.c
++++ b/drivers/usb/serial/ark3116.c
+@@ -35,11 +35,6 @@ static struct usb_device_id id_table [] = {
+ };
+ MODULE_DEVICE_TABLE(usb, id_table);
+
+-struct ark3116_private {
+- spinlock_t lock;
+- u8 termios_initialized;
+-};
+-
+ static inline void ARK3116_SND(struct usb_serial *serial, int seq,
+ __u8 request, __u8 requesttype,
+ __u16 value, __u16 index)
+@@ -82,22 +77,11 @@ static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
+ static int ark3116_attach(struct usb_serial *serial)
+ {
+ char *buf;
+- struct ark3116_private *priv;
+- int i;
+-
+- for (i = 0; i < serial->num_ports; ++i) {
+- priv = kzalloc(sizeof(struct ark3116_private), GFP_KERNEL);
+- if (!priv)
+- goto cleanup;
+- spin_lock_init(&priv->lock);
+-
+- usb_set_serial_port_data(serial->port[i], priv);
+- }
+
+ buf = kmalloc(1, GFP_KERNEL);
+ if (!buf) {
+ dbg("error kmalloc -> out of mem?");
+- goto cleanup;
++ return -ENOMEM;
+ }
+
+ /* 3 */
+@@ -149,13 +133,16 @@ static int ark3116_attach(struct usb_serial *serial)
+
+ kfree(buf);
+ return 0;
++}
+
+-cleanup:
+- for (--i; i >= 0; --i) {
+- kfree(usb_get_serial_port_data(serial->port[i]));
+- usb_set_serial_port_data(serial->port[i], NULL);
+- }
+- return -ENOMEM;
++static void ark3116_init_termios(struct tty_struct *tty)
++{
++ struct ktermios *termios = tty->termios;
++ *termios = tty_std_termios;
++ termios->c_cflag = B9600 | CS8
++ | CREAD | HUPCL | CLOCAL;
++ termios->c_ispeed = 9600;
++ termios->c_ospeed = 9600;
+ }
+
+ static void ark3116_set_termios(struct tty_struct *tty,
+@@ -163,10 +150,8 @@ static void ark3116_set_termios(struct tty_struct *tty,
+ struct ktermios *old_termios)
+ {
+ struct usb_serial *serial = port->serial;
+- struct ark3116_private *priv = usb_get_serial_port_data(port);
+ struct ktermios *termios = tty->termios;
+ unsigned int cflag = termios->c_cflag;
+- unsigned long flags;
+ int baud;
+ int ark3116_baud;
+ char *buf;
+@@ -176,16 +161,6 @@ static void ark3116_set_termios(struct tty_struct *tty,
+
+ dbg("%s - port %d", __func__, port->number);
+
+- spin_lock_irqsave(&priv->lock, flags);
+- if (!priv->termios_initialized) {
+- *termios = tty_std_termios;
+- termios->c_cflag = B9600 | CS8
+- | CREAD | HUPCL | CLOCAL;
+- termios->c_ispeed = 9600;
+- termios->c_ospeed = 9600;
+- priv->termios_initialized = 1;
+- }
+- spin_unlock_irqrestore(&priv->lock, flags);
+
+ cflag = termios->c_cflag;
+ termios->c_cflag &= ~(CMSPAR|CRTSCTS);
+@@ -455,6 +430,7 @@ static struct usb_serial_driver ark3116_device = {
+ .num_ports = 1,
+ .attach = ark3116_attach,
+ .set_termios = ark3116_set_termios,
++ .init_termios = ark3116_init_termios,
+ .ioctl = ark3116_ioctl,
+ .tiocmget = ark3116_tiocmget,
+ .open = ark3116_open,
+diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
+index 0e4f2e4..3e49b2e 100644
+--- a/drivers/usb/serial/console.c
++++ b/drivers/usb/serial/console.c
+@@ -16,6 +16,7 @@
+ #include <linux/slab.h>
+ #include <linux/tty.h>
+ #include <linux/console.h>
++#include <linux/serial.h>
+ #include <linux/usb.h>
+ #include <linux/usb/serial.h>
+
+@@ -63,7 +64,7 @@ static int usb_console_setup(struct console *co, char *options)
+ char *s;
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+- int retval = 0;
++ int retval;
+ struct tty_struct *tty = NULL;
+ struct ktermios *termios = NULL, dummy;
+
+@@ -116,13 +117,17 @@ static int usb_console_setup(struct console *co, char *options)
+ return -ENODEV;
+ }
+
+- port = serial->port[0];
++ retval = usb_autopm_get_interface(serial->interface);
++ if (retval)
++ goto error_get_interface;
++
++ port = serial->port[co->index - serial->minor];
+ tty_port_tty_set(&port->port, NULL);
+
+ info->port = port;
+
+ ++port->port.count;
+- if (port->port.count == 1) {
++ if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
+ if (serial->type->set_termios) {
+ /*
+ * allocate a fake tty so the driver can initialize
+@@ -168,6 +173,7 @@ static int usb_console_setup(struct console *co, char *options)
+ kfree(termios);
+ kfree(tty);
+ }
++ set_bit(ASYNCB_INITIALIZED, &port->port.flags);
+ }
+ /* Now that any required fake tty operations are completed restore
+ * the tty port count */
+@@ -175,18 +181,22 @@ static int usb_console_setup(struct console *co, char *options)
+ /* The console is special in terms of closing the device so
+ * indicate this port is now acting as a system console. */
+ port->console = 1;
+- retval = 0;
+
+-out:
++ mutex_unlock(&serial->disc_mutex);
+ return retval;
+-free_termios:
++
++ free_termios:
+ kfree(termios);
+ tty_port_tty_set(&port->port, NULL);
+-free_tty:
++ free_tty:
+ kfree(tty);
+-reset_open_count:
++ reset_open_count:
+ port->port.count = 0;
+- goto out;
++ usb_autopm_put_interface(serial->interface);
++ error_get_interface:
++ usb_serial_put(serial);
++ mutex_unlock(&serial->disc_mutex);
++ return retval;
+ }
+
+ static void usb_console_write(struct console *co,
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 985cbcf..b5275c4 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -399,12 +399,6 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port,
+
+ /* Configure the termios structure */
+ cp210x_get_termios(tty, port);
+-
+- /* Set the DTR and RTS pins low */
+- cp210x_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data
+- : port,
+- NULL, TIOCM_DTR | TIOCM_RTS, 0);
+-
+ return 0;
+ }
+
+diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
+index 59adfe1..27b5a27 100644
+--- a/drivers/usb/serial/cypress_m8.c
++++ b/drivers/usb/serial/cypress_m8.c
+@@ -659,15 +659,7 @@ static int cypress_open(struct tty_struct *tty,
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* Set termios */
+- result = cypress_write(tty, port, NULL, 0);
+-
+- if (result) {
+- dev_err(&port->dev,
+- "%s - failed setting the control lines - error %d\n",
+- __func__, result);
+- return result;
+- } else
+- dbg("%s - success setting the control lines", __func__);
++ cypress_send(port);
+
+ if (tty)
+ cypress_set_termios(tty, port, &priv->tmp_termios);
+@@ -1005,6 +997,8 @@ static void cypress_set_termios(struct tty_struct *tty,
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
++ /* We can't clean this one up as we don't know the device type
++ early enough */
+ if (!priv->termios_initialized) {
+ if (priv->chiptype == CT_EARTHMATE) {
+ *(tty->termios) = tty_std_termios;
+diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
+index 80cb347..3433f9d 100644
+--- a/drivers/usb/serial/empeg.c
++++ b/drivers/usb/serial/empeg.c
+@@ -90,8 +90,7 @@ 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_set_termios(struct tty_struct *tty,
+- struct usb_serial_port *port, struct ktermios *old_termios);
++static void empeg_init_termios(struct tty_struct *tty);
+ static void empeg_write_bulk_callback(struct urb *urb);
+ static void empeg_read_bulk_callback(struct urb *urb);
+
+@@ -123,7 +122,7 @@ static struct usb_serial_driver empeg_device = {
+ .throttle = empeg_throttle,
+ .unthrottle = empeg_unthrottle,
+ .attach = empeg_startup,
+- .set_termios = empeg_set_termios,
++ .init_termios = empeg_init_termios,
+ .write = empeg_write,
+ .write_room = empeg_write_room,
+ .chars_in_buffer = empeg_chars_in_buffer,
+@@ -150,9 +149,6 @@ static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
+
+ dbg("%s - port %d", __func__, port->number);
+
+- /* Force default termio settings */
+- empeg_set_termios(tty, port, NULL) ;
+-
+ bytes_in = 0;
+ bytes_out = 0;
+
+@@ -425,11 +421,9 @@ static int empeg_startup(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_init_termios(struct tty_struct *tty)
+ {
+ struct ktermios *termios = tty->termios;
+- dbg("%s - port %d", __func__, port->number);
+
+ /*
+ * The empeg-car player wants these particular tty settings.
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 8fec5d4..0cc78f9 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -176,6 +176,9 @@ static struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_SNIFFER_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) },
+ { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
+ { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
+@@ -694,6 +697,8 @@ static struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(DE_VID, WHT_PID) },
+ { USB_DEVICE(ADI_VID, ADI_GNICE_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
++ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
+ { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+@@ -702,6 +707,8 @@ static struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+ { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
++ { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) },
+ { }, /* Optional parameter entry */
+ { } /* Terminating entry */
+ };
+diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
+index 8c92b88..6f31e0d 100644
+--- a/drivers/usb/serial/ftdi_sio.h
++++ b/drivers/usb/serial/ftdi_sio.h
+@@ -81,6 +81,9 @@
+
+ /* OpenDCC (www.opendcc.de) product id */
+ #define FTDI_OPENDCC_PID 0xBFD8
++#define FTDI_OPENDCC_SNIFFER_PID 0xBFD9
++#define FTDI_OPENDCC_THROTTLE_PID 0xBFDA
++#define FTDI_OPENDCC_GATEWAY_PID 0xBFDB
+
+ /* Sprog II (Andrew Crosland's SprogII DCC interface) */
+ #define FTDI_SPROG_II 0xF0C8
+@@ -930,6 +933,7 @@
+ */
+ #define ADI_VID 0x0456
+ #define ADI_GNICE_PID 0xF000
++#define ADI_GNICEPLUS_PID 0xF001
+
+ /*
+ * JETI SPECTROMETER SPECBOS 1201
+@@ -968,6 +972,12 @@
+ #define MARVELL_OPENRD_PID 0x9e90
+
+ /*
++ * Hameg HO820 and HO870 interface (using VID 0x0403)
++ */
++#define HAMEG_HO820_PID 0xed74
++#define HAMEG_HO870_PID 0xed71
++
++/*
+ * BmRequestType: 1100 0000b
+ * bRequest: FTDI_E2_READ
+ * wValue: 0
+diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
+index 96873a7..af6df6c 100644
+--- a/drivers/usb/serial/iuu_phoenix.c
++++ b/drivers/usb/serial/iuu_phoenix.c
+@@ -71,7 +71,6 @@ struct iuu_private {
+ spinlock_t lock; /* store irq state */
+ wait_queue_head_t delta_msr_wait;
+ u8 line_status;
+- u8 termios_initialized;
+ int tiostatus; /* store IUART SIGNAL for tiocmget call */
+ u8 reset; /* if 1 reset is needed */
+ int poll; /* number of poll */
+@@ -1018,6 +1017,18 @@ static void iuu_close(struct usb_serial_port *port)
+ }
+ }
+
++static void iuu_init_termios(struct tty_struct *tty)
++{
++ *(tty->termios) = tty_std_termios;
++ tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
++ | TIOCM_CTS | CSTOPB | PARENB;
++ tty->termios->c_ispeed = 9600;
++ tty->termios->c_ospeed = 9600;
++ tty->termios->c_lflag = 0;
++ tty->termios->c_oflag = 0;
++ tty->termios->c_iflag = 0;
++}
++
+ static int iuu_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
+ {
+@@ -1025,7 +1036,6 @@ static int iuu_open(struct tty_struct *tty,
+ u8 *buf;
+ int result;
+ u32 actual;
+- unsigned long flags;
+ struct iuu_private *priv = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d", __func__, port->number);
+@@ -1064,21 +1074,7 @@ static int iuu_open(struct tty_struct *tty,
+ port->bulk_in_buffer, 512,
+ NULL, NULL);
+
+- /* set the termios structure */
+- spin_lock_irqsave(&priv->lock, flags);
+- if (tty && !priv->termios_initialized) {
+- *(tty->termios) = tty_std_termios;
+- tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
+- | TIOCM_CTS | CSTOPB | PARENB;
+- tty->termios->c_ispeed = 9600;
+- tty->termios->c_ospeed = 9600;
+- tty->termios->c_lflag = 0;
+- tty->termios->c_oflag = 0;
+- tty->termios->c_iflag = 0;
+- priv->termios_initialized = 1;
+- priv->poll = 0;
+- }
+- spin_unlock_irqrestore(&priv->lock, flags);
++ priv->poll = 0;
+
+ /* initialize writebuf */
+ #define FISH(a, b, c, d) do { \
+@@ -1201,6 +1197,7 @@ static struct usb_serial_driver iuu_device = {
+ .tiocmget = iuu_tiocmget,
+ .tiocmset = iuu_tiocmset,
+ .set_termios = iuu_set_termios,
++ .init_termios = iuu_init_termios,
+ .attach = iuu_startup,
+ .release = iuu_release,
+ };
+diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
+index 6db0e56..46d47d1 100644
+--- a/drivers/usb/serial/kobil_sct.c
++++ b/drivers/usb/serial/kobil_sct.c
+@@ -85,7 +85,7 @@ static void kobil_read_int_callback(struct urb *urb);
+ static void kobil_write_callback(struct urb *purb);
+ static void kobil_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
+-
++static void kobil_init_termios(struct tty_struct *tty);
+
+ static struct usb_device_id id_table [] = {
+ { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
+@@ -120,6 +120,7 @@ static struct usb_serial_driver kobil_device = {
+ .release = kobil_release,
+ .ioctl = kobil_ioctl,
+ .set_termios = kobil_set_termios,
++ .init_termios = kobil_init_termios,
+ .tiocmget = kobil_tiocmget,
+ .tiocmset = kobil_tiocmset,
+ .open = kobil_open,
+@@ -210,6 +211,15 @@ static void kobil_release(struct usb_serial *serial)
+ kfree(usb_get_serial_port_data(serial->port[i]));
+ }
+
++static void kobil_init_termios(struct tty_struct *tty)
++{
++ /* Default to echo off and other sane device settings */
++ tty->termios->c_lflag = 0;
++ tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
++ tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
++ /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
++ tty->termios->c_oflag &= ~ONLCR;
++}
+
+ static int kobil_open(struct tty_struct *tty,
+ struct usb_serial_port *port, struct file *filp)
+@@ -226,16 +236,6 @@ static int kobil_open(struct tty_struct *tty,
+ /* someone sets the dev to 0 if the close method has been called */
+ port->interrupt_in_urb->dev = port->serial->dev;
+
+- if (tty) {
+-
+- /* Default to echo off and other sane device settings */
+- tty->termios->c_lflag = 0;
+- tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN |
+- XCASE);
+- tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
+- /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
+- tty->termios->c_oflag &= ~ONLCR;
+- }
+ /* allocate memory for transfer buffer */
+ transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
+ if (!transfer_buffer)
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c784ddb..0101548 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -292,6 +292,7 @@ static int option_resume(struct usb_serial *serial);
+
+ #define TELIT_VENDOR_ID 0x1bc7
+ #define TELIT_PRODUCT_UC864E 0x1003
++#define TELIT_PRODUCT_UC864G 0x1004
+
+ /* ZTE PRODUCTS */
+ #define ZTE_VENDOR_ID 0x19d2
+@@ -300,6 +301,7 @@ static int option_resume(struct usb_serial *serial);
+ #define ZTE_PRODUCT_MF626 0x0031
+ #define ZTE_PRODUCT_CDMA_TECH 0xfffe
+ #define ZTE_PRODUCT_AC8710 0xfff1
++#define ZTE_PRODUCT_AC2726 0xfff5
+
+ #define BENQ_VENDOR_ID 0x04a5
+ #define BENQ_PRODUCT_H10 0x4068
+@@ -503,6 +505,7 @@ static struct usb_device_id option_ids[] = {
+ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
+ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
++ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) },
+@@ -572,6 +575,7 @@ static struct usb_device_id option_ids[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
+ { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
+ { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
+ { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
+diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
+index 3cece27..ef34cff 100644
+--- a/drivers/usb/serial/oti6858.c
++++ b/drivers/usb/serial/oti6858.c
+@@ -146,6 +146,7 @@ static int oti6858_open(struct tty_struct *tty,
+ static void oti6858_close(struct usb_serial_port *port);
+ static void oti6858_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old);
++static void oti6858_init_termios(struct tty_struct *tty);
+ static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+ static void oti6858_read_int_callback(struct urb *urb);
+@@ -186,6 +187,7 @@ static struct usb_serial_driver oti6858_device = {
+ .write = oti6858_write,
+ .ioctl = oti6858_ioctl,
+ .set_termios = oti6858_set_termios,
++ .init_termios = oti6858_init_termios,
+ .tiocmget = oti6858_tiocmget,
+ .tiocmset = oti6858_tiocmset,
+ .read_bulk_callback = oti6858_read_bulk_callback,
+@@ -206,7 +208,6 @@ struct oti6858_private {
+ struct {
+ u8 read_urb_in_use;
+ u8 write_urb_in_use;
+- u8 termios_initialized;
+ } flags;
+ struct delayed_work delayed_write_work;
+
+@@ -447,6 +448,14 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty)
+ return chars;
+ }
+
++static void oti6858_init_termios(struct tty_struct *tty)
++{
++ *(tty->termios) = tty_std_termios;
++ tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
++ tty->termios->c_ispeed = 38400;
++ tty->termios->c_ospeed = 38400;
++}
++
+ static void oti6858_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
+ {
+@@ -464,16 +473,6 @@ static void oti6858_set_termios(struct tty_struct *tty,
+ return;
+ }
+
+- spin_lock_irqsave(&priv->lock, flags);
+- if (!priv->flags.termios_initialized) {
+- *(tty->termios) = tty_std_termios;
+- tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+- tty->termios->c_ispeed = 38400;
+- tty->termios->c_ospeed = 38400;
+- priv->flags.termios_initialized = 1;
+- }
+- spin_unlock_irqrestore(&priv->lock, flags);
+-
+ cflag = tty->termios->c_cflag;
+
+ spin_lock_irqsave(&priv->lock, flags);
+diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
+index 3e86815..124d5ae 100644
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -96,6 +96,7 @@ static struct usb_device_id id_table [] = {
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+ { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
++ { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
+ { } /* Terminating entry */
+ };
+
+diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
+index ee9505e..d640dc9 100644
+--- a/drivers/usb/serial/pl2303.h
++++ b/drivers/usb/serial/pl2303.h
+@@ -130,3 +130,7 @@
+ /* Sony, USB data cable for CMD-Jxx mobile phones */
+ #define SONY_VENDOR_ID 0x054c
+ #define SONY_QN3USB_PRODUCT_ID 0x0437
++
++/* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
++#define SANWA_VENDOR_ID 0x11ad
++#define SANWA_PRODUCT_ID 0x0001
+diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
+index 3c249d8..993a6d5 100644
+--- a/drivers/usb/serial/spcp8x5.c
++++ b/drivers/usb/serial/spcp8x5.c
+@@ -299,7 +299,6 @@ struct spcp8x5_private {
+ wait_queue_head_t delta_msr_wait;
+ u8 line_control;
+ u8 line_status;
+- u8 termios_initialized;
+ };
+
+ /* desc : when device plug in,this function would be called.
+@@ -498,6 +497,15 @@ static void spcp8x5_close(struct usb_serial_port *port)
+ dev_dbg(&port->dev, "usb_unlink_urb(read_urb) = %d\n", result);
+ }
+
++static void spcp8x5_init_termios(struct tty_struct *tty)
++{
++ /* for the 1st time call this function */
++ *(tty->termios) = tty_std_termios;
++ tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
++ tty->termios->c_ispeed = 115200;
++ tty->termios->c_ospeed = 115200;
++}
++
+ /* set the serial param for transfer. we should check if we really need to
+ * transfer. if we set flow control we should do this too. */
+ static void spcp8x5_set_termios(struct tty_struct *tty,
+@@ -514,16 +522,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
+ int i;
+ u8 control;
+
+- /* for the 1st time call this function */
+- spin_lock_irqsave(&priv->lock, flags);
+- if (!priv->termios_initialized) {
+- *(tty->termios) = tty_std_termios;
+- tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+- tty->termios->c_ispeed = 115200;
+- tty->termios->c_ospeed = 115200;
+- priv->termios_initialized = 1;
+- }
+- spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* check that they really want us to change something */
+ if (!tty_termios_hw_change(tty->termios, old_termios))
+@@ -1011,6 +1009,7 @@ static struct usb_serial_driver spcp8x5_device = {
+ .carrier_raised = spcp8x5_carrier_raised,
+ .write = spcp8x5_write,
+ .set_termios = spcp8x5_set_termios,
++ .init_termios = spcp8x5_init_termios,
+ .ioctl = spcp8x5_ioctl,
+ .tiocmget = spcp8x5_tiocmget,
+ .tiocmset = spcp8x5_tiocmset,
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+index 99188c9..a0702db 100644
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -43,8 +43,6 @@
+ #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg at kroah.com, http://www.kroah.com/linux/"
+ #define DRIVER_DESC "USB Serial Driver core"
+
+-static void port_free(struct usb_serial_port *port);
+-
+ /* Driver structure we register with the USB core */
+ static struct usb_driver usb_serial_driver = {
+ .name = "usbserial",
+@@ -68,6 +66,11 @@ static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
+ static DEFINE_MUTEX(table_lock);
+ static LIST_HEAD(usb_serial_driver_list);
+
++/*
++ * Look up the serial structure. If it is found and it hasn't been
++ * disconnected, return with its disc_mutex held and its refcount
++ * incremented. Otherwise return NULL.
++ */
+ struct usb_serial *usb_serial_get_by_index(unsigned index)
+ {
+ struct usb_serial *serial;
+@@ -75,8 +78,15 @@ struct usb_serial *usb_serial_get_by_index(unsigned index)
+ mutex_lock(&table_lock);
+ serial = serial_table[index];
+
+- if (serial)
+- kref_get(&serial->kref);
++ if (serial) {
++ mutex_lock(&serial->disc_mutex);
++ if (serial->disconnected) {
++ mutex_unlock(&serial->disc_mutex);
++ serial = NULL;
++ } else {
++ kref_get(&serial->kref);
++ }
++ }
+ mutex_unlock(&table_lock);
+ return serial;
+ }
+@@ -125,8 +135,10 @@ static void return_serial(struct usb_serial *serial)
+
+ dbg("%s", __func__);
+
++ mutex_lock(&table_lock);
+ for (i = 0; i < serial->num_ports; ++i)
+ serial_table[serial->minor + i] = NULL;
++ mutex_unlock(&table_lock);
+ }
+
+ static void destroy_serial(struct kref *kref)
+@@ -145,161 +157,157 @@ static void destroy_serial(struct kref *kref)
+
+ serial->type->release(serial);
+
+- for (i = 0; i < serial->num_ports; ++i) {
++ /* Now that nothing is using the ports, they can be freed */
++ for (i = 0; i < serial->num_port_pointers; ++i) {
+ port = serial->port[i];
+- if (port)
++ if (port) {
++ port->serial = NULL;
+ 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 */
+- if (serial->num_ports < serial->num_port_pointers) {
+- for (i = serial->num_ports;
+- i < serial->num_port_pointers; ++i) {
+- port = serial->port[i];
+- if (port)
+- port_free(port);
+ }
+ }
+
+ usb_put_dev(serial->dev);
+-
+- /* free up any memory that we allocated */
+ kfree(serial);
+ }
+
+ void usb_serial_put(struct usb_serial *serial)
+ {
+- mutex_lock(&table_lock);
+ kref_put(&serial->kref, destroy_serial);
+- mutex_unlock(&table_lock);
+ }
+
+ /*****************************************************************************
+ * Driver tty interface functions
+ *****************************************************************************/
+-static int serial_open (struct tty_struct *tty, struct file *filp)
++
++/**
++ * serial_install - install tty
++ * @driver: the driver (USB in our case)
++ * @tty: the tty being created
++ *
++ * Create the termios objects for this tty. We use the default
++ * USB serial settings but permit them to be overridden by
++ * serial->type->init_termios.
++ *
++ * This is the first place a new tty gets used. Hence this is where we
++ * acquire references to the usb_serial structure and the driver module,
++ * where we store a pointer to the port, and where we do an autoresume.
++ * All these actions are reversed in serial_release().
++ */
++static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
+ {
++ int idx = tty->index;
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+- unsigned int portNumber;
+- int retval = 0;
+- int first = 0;
++ int retval = -ENODEV;
+
+ dbg("%s", __func__);
+
+- /* get the serial object associated with this tty pointer */
+- serial = usb_serial_get_by_index(tty->index);
+- if (!serial) {
+- tty->driver_data = NULL;
+- return -ENODEV;
+- }
++ serial = usb_serial_get_by_index(idx);
++ if (!serial)
++ return retval;
+
+- mutex_lock(&serial->disc_mutex);
+- portNumber = tty->index - serial->minor;
+- port = serial->port[portNumber];
+- if (!port || serial->disconnected)
+- retval = -ENODEV;
+- else
+- get_device(&port->dev);
+- /*
+- * Note: Our locking order requirement does not allow port->mutex
+- * to be acquired while serial->disc_mutex is held.
+- */
+- mutex_unlock(&serial->disc_mutex);
++ port = serial->port[idx - serial->minor];
++ if (!port)
++ goto error_no_port;
++ if (!try_module_get(serial->type->driver.owner))
++ goto error_module_get;
++
++ /* perform the standard setup */
++ retval = tty_init_termios(tty);
+ if (retval)
+- goto bailout_serial_put;
++ goto error_init_termios;
+
+- if (mutex_lock_interruptible(&port->mutex)) {
+- retval = -ERESTARTSYS;
+- goto bailout_port_put;
+- }
++ retval = usb_autopm_get_interface(serial->interface);
++ if (retval)
++ goto error_get_interface;
++
++ mutex_unlock(&serial->disc_mutex);
+
+- ++port->port.count;
++ /* allow the driver to update the settings */
++ if (serial->type->init_termios)
++ serial->type->init_termios(tty);
+
+- /* set up our port structure making the tty driver
+- * remember our port object, and us it */
+ tty->driver_data = port;
+- tty_port_tty_set(&port->port, tty);
+
+- /* If the console is attached, the device is already open */
+- if (port->port.count == 1 && !port->console) {
+- first = 1;
+- /* lock this module before we call it
+- * this may fail, which means we must bail out,
+- * safe because we are called with BKL held */
+- if (!try_module_get(serial->type->driver.owner)) {
+- retval = -ENODEV;
+- goto bailout_mutex_unlock;
+- }
++ /* Final install (we use the default method) */
++ tty_driver_kref_get(driver);
++ tty->count++;
++ driver->ttys[idx] = tty;
++ return retval;
+
++ error_get_interface:
++ error_init_termios:
++ module_put(serial->type->driver.owner);
++ error_module_get:
++ error_no_port:
++ usb_serial_put(serial);
++ mutex_unlock(&serial->disc_mutex);
++ return retval;
++}
++
++static int serial_open(struct tty_struct *tty, struct file *filp)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct usb_serial *serial = port->serial;
++ int retval;
++
++ dbg("%s - port %d", __func__, port->number);
++
++ spin_lock_irq(&port->port.lock);
++ if (!tty_hung_up_p(filp))
++ ++port->port.count;
++ spin_unlock_irq(&port->port.lock);
++ tty_port_tty_set(&port->port, tty);
++
++ /* Do the device-specific open only if the hardware isn't
++ * already initialized.
++ */
++ if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
++ if (mutex_lock_interruptible(&port->mutex))
++ return -ERESTARTSYS;
+ mutex_lock(&serial->disc_mutex);
+ if (serial->disconnected)
+ retval = -ENODEV;
+ else
+- retval = usb_autopm_get_interface(serial->interface);
+- if (retval)
+- goto bailout_module_put;
+-
+- /* only call the device specific open if this
+- * is the first time the port is opened */
+- retval = serial->type->open(tty, port, filp);
+- if (retval)
+- goto bailout_interface_put;
++ retval = port->serial->type->open(tty, port, filp);
+ mutex_unlock(&serial->disc_mutex);
++ mutex_unlock(&port->mutex);
++ if (retval)
++ return retval;
+ set_bit(ASYNCB_INITIALIZED, &port->port.flags);
+ }
+- mutex_unlock(&port->mutex);
++
+ /* Now do the correct tty layer semantics */
+ retval = tty_port_block_til_ready(&port->port, tty, filp);
+- if (retval == 0) {
+- if (!first)
+- usb_serial_put(serial);
+- return 0;
+- }
+- mutex_lock(&port->mutex);
+- if (first == 0)
+- goto bailout_mutex_unlock;
+- /* Undo the initial port actions */
+- mutex_lock(&serial->disc_mutex);
+-bailout_interface_put:
+- usb_autopm_put_interface(serial->interface);
+-bailout_module_put:
+- mutex_unlock(&serial->disc_mutex);
+- module_put(serial->type->driver.owner);
+-bailout_mutex_unlock:
+- port->port.count = 0;
+- tty->driver_data = NULL;
+- tty_port_tty_set(&port->port, NULL);
+- mutex_unlock(&port->mutex);
+-bailout_port_put:
+- put_device(&port->dev);
+-bailout_serial_put:
+- usb_serial_put(serial);
+ return retval;
+ }
+
+ /**
+- * serial_do_down - shut down hardware
+- * @port: port to shut down
+- *
+- * Shut down a USB port unless it is the console. We never shut down the
+- * console hardware as it will always be in use.
++ * serial_down - shut down hardware
++ * @port: port to shut down
+ *
+- * Don't free any resources at this point
++ * Shut down a USB serial port unless it is the console. We never
++ * shut down the console hardware as it will always be in use.
+ */
+-static void serial_do_down(struct usb_serial_port *port)
++static void serial_down(struct usb_serial_port *port)
+ {
+ struct usb_serial_driver *drv = port->serial->type;
+ struct usb_serial *serial;
+ struct module *owner;
+
+- /* The console is magical, do not hang up the console hardware
+- or there will be tears */
++ /*
++ * The console is magical. Do not hang up the console hardware
++ * or there will be tears.
++ */
+ if (port->console)
+ return;
+
++ /* Don't call the close method if the hardware hasn't been
++ * initialized.
++ */
++ if (!test_and_clear_bit(ASYNCB_INITIALIZED, &port->port.flags))
++ return;
++
+ mutex_lock(&port->mutex);
+ serial = port->serial;
+ owner = serial->type->driver.owner;
+@@ -310,79 +318,69 @@ static void serial_do_down(struct usb_serial_port *port)
+ mutex_unlock(&port->mutex);
+ }
+
+-/**
+- * serial_do_free - free resources post close/hangup
+- * @port: port to free up
+- *
+- * Do the resource freeing and refcount dropping for the port. We must
+- * be careful about ordering and we must avoid freeing up the console.
+- */
+-
+-static void serial_do_free(struct usb_serial_port *port)
++static void serial_hangup(struct tty_struct *tty)
+ {
+- struct usb_serial *serial;
+- struct module *owner;
++ struct usb_serial_port *port = tty->driver_data;
+
+- /* The console is magical, do not hang up the console hardware
+- or there will be tears */
+- if (port->console)
+- return;
++ dbg("%s - port %d", __func__, port->number);
+
+- serial = port->serial;
+- owner = serial->type->driver.owner;
+- put_device(&port->dev);
+- /* Mustn't dereference port any more */
+- mutex_lock(&serial->disc_mutex);
+- if (!serial->disconnected)
+- usb_autopm_put_interface(serial->interface);
+- mutex_unlock(&serial->disc_mutex);
+- usb_serial_put(serial);
+- /* Mustn't dereference serial any more */
+- module_put(owner);
++ serial_down(port);
++ tty_port_hangup(&port->port);
+ }
+
+ static void serial_close(struct tty_struct *tty, struct file *filp)
+ {
+ struct usb_serial_port *port = tty->driver_data;
+
+- if (!port)
+- return;
+-
+ dbg("%s - port %d", __func__, port->number);
+
+- /* FIXME:
+- This leaves a very narrow race. Really we should do the
+- serial_do_free() on tty->shutdown(), but tty->shutdown can
+- be called from IRQ context and serial_do_free can sleep.
+-
+- The right fix is probably to make the tty free (which is rare)
+- and thus tty->shutdown() occur via a work queue and simplify all
+- the drivers that use it.
+- */
+- if (tty_hung_up_p(filp)) {
+- /* serial_hangup already called serial_down at this point.
+- Another user may have already reopened the port but
+- serial_do_free is refcounted */
+- serial_do_free(port);
++ if (tty_hung_up_p(filp))
+ return;
+- }
+-
+ if (tty_port_close_start(&port->port, tty, filp) == 0)
+ return;
+-
+- serial_do_down(port);
++ serial_down(port);
+ tty_port_close_end(&port->port, tty);
+ tty_port_tty_set(&port->port, NULL);
+- serial_do_free(port);
+ }
+
+-static void serial_hangup(struct tty_struct *tty)
++/**
++ * serial_release - free resources post close/hangup
++ * @port: port to free up
++ *
++ * Do the resource freeing and refcount dropping for the port.
++ * Avoid freeing the console.
++ *
++ * Called when the last tty kref is dropped.
++ */
++static void serial_release(struct tty_struct *tty)
+ {
+ struct usb_serial_port *port = tty->driver_data;
+- serial_do_down(port);
+- tty_port_hangup(&port->port);
+- /* We must not free port yet - the USB serial layer depends on it's
+- continued existence */
++ struct usb_serial *serial;
++ struct module *owner;
++
++ /* The console is magical. Do not hang up the console hardware
++ * or there will be tears.
++ */
++ if (port->console)
++ return;
++
++ dbg("%s - port %d", __func__, port->number);
++
++ /* Standard shutdown processing */
++ tty_shutdown(tty);
++
++ tty->driver_data = NULL;
++
++ serial = port->serial;
++ owner = serial->type->driver.owner;
++
++ mutex_lock(&serial->disc_mutex);
++ if (!serial->disconnected)
++ usb_autopm_put_interface(serial->interface);
++ mutex_unlock(&serial->disc_mutex);
++
++ usb_serial_put(serial);
++ module_put(owner);
+ }
+
+ static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+@@ -527,6 +525,7 @@ static int serial_proc_show(struct seq_file *m, void *v)
+
+ seq_putc(m, '\n');
+ usb_serial_put(serial);
++ mutex_unlock(&serial->disc_mutex);
+ }
+ return 0;
+ }
+@@ -596,14 +595,6 @@ static void usb_serial_port_work(struct work_struct *work)
+ tty_kref_put(tty);
+ }
+
+-static void port_release(struct device *dev)
+-{
+- struct usb_serial_port *port = to_usb_serial_port(dev);
+-
+- dbg ("%s - %s", __func__, dev_name(dev));
+- port_free(port);
+-}
+-
+ static void kill_traffic(struct usb_serial_port *port)
+ {
+ usb_kill_urb(port->read_urb);
+@@ -623,8 +614,12 @@ static void kill_traffic(struct usb_serial_port *port)
+ usb_kill_urb(port->interrupt_out_urb);
+ }
+
+-static void port_free(struct usb_serial_port *port)
++static void port_release(struct device *dev)
+ {
++ struct usb_serial_port *port = to_usb_serial_port(dev);
++
++ dbg ("%s - %s", __func__, dev_name(dev));
++
+ /*
+ * Stop all the traffic before cancelling the work, so that
+ * nobody will restart it by calling usb_serial_port_softint.
+@@ -935,6 +930,11 @@ int usb_serial_probe(struct usb_interface *interface,
+ mutex_init(&port->mutex);
+ INIT_WORK(&port->work, usb_serial_port_work);
+ serial->port[i] = port;
++ port->dev.parent = &interface->dev;
++ port->dev.driver = NULL;
++ port->dev.bus = &usb_serial_bus_type;
++ port->dev.release = &port_release;
++ device_initialize(&port->dev);
+ }
+
+ /* set up the endpoint information */
+@@ -1077,15 +1077,10 @@ int usb_serial_probe(struct usb_interface *interface,
+ /* register all of the individual ports with the driver core */
+ for (i = 0; i < num_ports; ++i) {
+ port = serial->port[i];
+- port->dev.parent = &interface->dev;
+- port->dev.driver = NULL;
+- port->dev.bus = &usb_serial_bus_type;
+- port->dev.release = &port_release;
+-
+ dev_set_name(&port->dev, "ttyUSB%d", port->number);
+ dbg ("%s - registering %s", __func__, dev_name(&port->dev));
+ port->dev_state = PORT_REGISTERING;
+- retval = device_register(&port->dev);
++ retval = device_add(&port->dev);
+ if (retval) {
+ dev_err(&port->dev, "Error registering port device, "
+ "continuing\n");
+@@ -1103,39 +1098,7 @@ exit:
+ return 0;
+
+ probe_error:
+- for (i = 0; i < num_bulk_in; ++i) {
+- port = serial->port[i];
+- if (!port)
+- continue;
+- usb_free_urb(port->read_urb);
+- kfree(port->bulk_in_buffer);
+- }
+- for (i = 0; i < num_bulk_out; ++i) {
+- port = serial->port[i];
+- if (!port)
+- continue;
+- usb_free_urb(port->write_urb);
+- kfree(port->bulk_out_buffer);
+- }
+- for (i = 0; i < num_interrupt_in; ++i) {
+- port = serial->port[i];
+- if (!port)
+- continue;
+- usb_free_urb(port->interrupt_in_urb);
+- kfree(port->interrupt_in_buffer);
+- }
+- for (i = 0; i < num_interrupt_out; ++i) {
+- port = serial->port[i];
+- if (!port)
+- continue;
+- usb_free_urb(port->interrupt_out_urb);
+- kfree(port->interrupt_out_buffer);
+- }
+-
+- /* free up any memory that we allocated */
+- for (i = 0; i < serial->num_port_pointers; ++i)
+- kfree(serial->port[i]);
+- kfree(serial);
++ usb_serial_put(serial);
+ return -EIO;
+ }
+ EXPORT_SYMBOL_GPL(usb_serial_probe);
+@@ -1161,10 +1124,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
+ if (port) {
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ if (tty) {
+- /* The hangup will occur asynchronously but
+- the object refcounts will sort out all the
+- cleanup */
+- tty_hangup(tty);
++ tty_vhangup(tty);
+ tty_kref_put(tty);
+ }
+ kill_traffic(port);
+@@ -1189,8 +1149,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
+ }
+ serial->type->disconnect(serial);
+
+- /* let the last holder of this object
+- * cause it to be cleaned up */
++ /* let the last holder of this object cause it to be cleaned up */
+ usb_serial_put(serial);
+ dev_info(dev, "device disconnected\n");
+ }
+@@ -1246,6 +1205,8 @@ static const struct tty_operations serial_ops = {
+ .chars_in_buffer = serial_chars_in_buffer,
+ .tiocmget = serial_tiocmget,
+ .tiocmset = serial_tiocmset,
++ .shutdown = serial_release,
++ .install = serial_install,
+ .proc_fops = &serial_proc_fops,
+ };
+
+diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
+index 8d126dd..f7232b1 100644
+--- a/drivers/usb/serial/whiteheat.c
++++ b/drivers/usb/serial/whiteheat.c
+@@ -259,7 +259,7 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command,
+ __u8 *data, __u8 datasize);
+ static int firm_open(struct usb_serial_port *port);
+ static int firm_close(struct usb_serial_port *port);
+-static int firm_setup_port(struct tty_struct *tty);
++static void firm_setup_port(struct tty_struct *tty);
+ static int firm_set_rts(struct usb_serial_port *port, __u8 onoff);
+ static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff);
+ static int firm_set_break(struct usb_serial_port *port, __u8 onoff);
+@@ -1211,7 +1211,7 @@ static int firm_close(struct usb_serial_port *port)
+ }
+
+
+-static int firm_setup_port(struct tty_struct *tty)
++static void firm_setup_port(struct tty_struct *tty)
+ {
+ struct usb_serial_port *port = tty->driver_data;
+ struct whiteheat_port_settings port_settings;
+@@ -1286,7 +1286,7 @@ static int firm_setup_port(struct tty_struct *tty)
+ port_settings.lloop = 0;
+
+ /* now send the message to the device */
+- return firm_send_command(port, WHITEHEAT_SETUP_PORT,
++ firm_send_command(port, WHITEHEAT_SETUP_PORT,
+ (__u8 *)&port_settings, sizeof(port_settings));
+ }
+
+diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
+index ec17c96..105d900 100644
+--- a/drivers/usb/storage/initializers.c
++++ b/drivers/usb/storage/initializers.c
+@@ -102,5 +102,5 @@ int usb_stor_huawei_e220_init(struct us_data *us)
+ USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+ 0x01, 0x0, NULL, 0x0, 1000);
+ US_DEBUGP("Huawei mode set result is %d\n", result);
+- return (result ? 0 : -ENODEV);
++ return 0;
+ }
+diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
+index 380233b..80e65f2 100644
+--- a/drivers/usb/storage/onetouch.c
++++ b/drivers/usb/storage/onetouch.c
+@@ -163,7 +163,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action)
+ usb_kill_urb(onetouch->irq);
+ break;
+ case US_RESUME:
+- if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0)
++ if (usb_submit_urb(onetouch->irq, GFP_NOIO) != 0)
+ dev_err(&onetouch->irq->dev->dev,
+ "usb_submit_urb failed\n");
+ break;
+diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
+index 3a44695..29ff5ea 100644
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -114,6 +114,7 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1;
+ static int fbcon_is_default = 1;
+ static int fbcon_has_exited;
+ static int primary_device = -1;
++static int fbcon_has_console_bind;
+
+ #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
+ static int map_override;
+@@ -544,6 +545,8 @@ static int fbcon_takeover(int show_logo)
+ con2fb_map[i] = -1;
+ }
+ info_idx = -1;
++ } else {
++ fbcon_has_console_bind = 1;
+ }
+
+ return err;
+@@ -2923,6 +2926,10 @@ static int fbcon_unbind(void)
+
+ ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
+ fbcon_is_default);
++
++ if (!ret)
++ fbcon_has_console_bind = 0;
++
+ return ret;
+ }
+ #else
+@@ -2936,6 +2943,9 @@ static int fbcon_fb_unbind(int idx)
+ {
+ int i, new_idx = -1, ret = 0;
+
++ if (!fbcon_has_console_bind)
++ return 0;
++
+ for (i = first_fb_vc; i <= last_fb_vc; i++) {
+ if (con2fb_map[i] != idx &&
+ con2fb_map[i] != -1) {
+diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
+index 5a72083..adf9632 100644
+--- a/drivers/video/s3c-fb.c
++++ b/drivers/video/s3c-fb.c
+@@ -1036,7 +1036,7 @@ static int s3c_fb_resume(struct platform_device *pdev)
+
+ static struct platform_driver s3c_fb_driver = {
+ .probe = s3c_fb_probe,
+- .remove = s3c_fb_remove,
++ .remove = __devexit_p(s3c_fb_remove),
+ .suspend = s3c_fb_suspend,
+ .resume = s3c_fb_resume,
+ .driver = {
+diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
+index 705c853..bef4aae 100644
+--- a/drivers/video/sis/vstruct.h
++++ b/drivers/video/sis/vstruct.h
+@@ -342,7 +342,7 @@ struct SiS_Private
+ unsigned short SiS_RY4COE;
+ unsigned short SiS_LCDHDES;
+ unsigned short SiS_LCDVDES;
+- unsigned short SiS_DDC_Port;
++ SISIOADDRESS SiS_DDC_Port;
+ unsigned short SiS_DDC_Index;
+ unsigned short SiS_DDC_Data;
+ unsigned short SiS_DDC_NData;
+diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
+index ec2a39b..7c28434 100644
+--- a/drivers/xen/Makefile
++++ b/drivers/xen/Makefile
+@@ -1,6 +1,9 @@
+ obj-y += grant-table.o features.o events.o manage.o
+ obj-y += xenbus/
+
++nostackp := $(call cc-option, -fno-stack-protector)
++CFLAGS_features.o := $(nostackp)
++
+ obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
+ obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
+ obj-$(CONFIG_XEN_BALLOON) += balloon.o
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 6084d63..3cfec69 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -572,9 +572,9 @@ require use of the stronger protocol */
+ #define CIFSSEC_MUST_LANMAN 0x10010
+ #define CIFSSEC_MUST_PLNTXT 0x20020
+ #ifdef CONFIG_CIFS_UPCALL
+-#define CIFSSEC_MASK 0xAF0AF /* allows weak security but also krb5 */
++#define CIFSSEC_MASK 0xBF0BF /* allows weak security but also krb5 */
+ #else
+-#define CIFSSEC_MASK 0xA70A7 /* current flags supported if weak */
++#define CIFSSEC_MASK 0xB70B7 /* current flags supported if weak */
+ #endif /* UPCALL */
+ #else /* do not allow weak pw hash */
+ #ifdef CONFIG_CIFS_UPCALL
+diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
+index b91851f..f0b53df 100644
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -797,6 +797,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
+ kfree(full_alg_name);
+ if (IS_ERR(crypt_stat->tfm)) {
+ rc = PTR_ERR(crypt_stat->tfm);
++ crypt_stat->tfm = NULL;
+ ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
+ "Error initializing cipher [%s]\n",
+ crypt_stat->cipher);
+@@ -1702,7 +1703,7 @@ ecryptfs_encrypt_filename(struct ecryptfs_filename *filename,
+ } else {
+ printk(KERN_ERR "%s: No support for requested filename "
+ "encryption method in this release\n", __func__);
+- rc = -ENOTSUPP;
++ rc = -EOPNOTSUPP;
+ goto out;
+ }
+ out:
+@@ -2166,7 +2167,7 @@ int ecryptfs_encrypt_and_encode_filename(
+ (*encoded_name)[(*encoded_name_size)] = '\0';
+ (*encoded_name_size)++;
+ } else {
+- rc = -ENOTSUPP;
++ rc = -EOPNOTSUPP;
+ }
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to encode "
+diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
+index 2f0945d..056fed6 100644
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -476,6 +476,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
+ struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
+ struct dentry *lower_dir_dentry;
+
++ dget(lower_dentry);
+ lower_dir_dentry = lock_parent(lower_dentry);
+ rc = vfs_unlink(lower_dir_inode, lower_dentry);
+ if (rc) {
+@@ -489,6 +490,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
+ d_drop(dentry);
+ out_unlock:
+ unlock_dir(lower_dir_dentry);
++ dput(lower_dentry);
+ return rc;
+ }
+
+diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
+index 259525c..c77438f 100644
+--- a/fs/ecryptfs/keystore.c
++++ b/fs/ecryptfs/keystore.c
+@@ -416,7 +416,9 @@ ecryptfs_find_global_auth_tok_for_sig(
+ &mount_crypt_stat->global_auth_tok_list,
+ mount_crypt_stat_list) {
+ if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) {
+- (*global_auth_tok) = walker;
++ rc = key_validate(walker->global_auth_tok_key);
++ if (!rc)
++ (*global_auth_tok) = walker;
+ goto out;
+ }
+ }
+@@ -612,7 +614,12 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
+ }
+ /* TODO: Support other key modules than passphrase for
+ * filename encryption */
+- BUG_ON(s->auth_tok->token_type != ECRYPTFS_PASSWORD);
++ if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
++ rc = -EOPNOTSUPP;
++ printk(KERN_INFO "%s: Filename encryption only supports "
++ "password tokens\n", __func__);
++ goto out_free_unlock;
++ }
+ sg_init_one(
+ &s->hash_sg,
+ (u8 *)s->auth_tok->token.password.session_key_encryption_key,
+@@ -910,7 +917,12 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
+ }
+ /* TODO: Support other key modules than passphrase for
+ * filename encryption */
+- BUG_ON(s->auth_tok->token_type != ECRYPTFS_PASSWORD);
++ if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
++ rc = -EOPNOTSUPP;
++ printk(KERN_INFO "%s: Filename encryption only supports "
++ "password tokens\n", __func__);
++ goto out_free_unlock;
++ }
+ rc = crypto_blkcipher_setkey(
+ s->desc.tfm,
+ s->auth_tok->token.password.session_key_encryption_key,
+@@ -1316,8 +1328,10 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
+ rc = -EINVAL;
+ goto out_free;
+ }
+- ecryptfs_cipher_code_to_string(crypt_stat->cipher,
+- (u16)data[(*packet_size)]);
++ rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher,
++ (u16)data[(*packet_size)]);
++ if (rc)
++ goto out_free;
+ /* A little extra work to differentiate among the AES key
+ * sizes; see RFC2440 */
+ switch(data[(*packet_size)++]) {
+@@ -1328,7 +1342,9 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
+ crypt_stat->key_size =
+ (*new_auth_tok)->session_key.encrypted_key_size;
+ }
+- ecryptfs_init_crypt_ctx(crypt_stat);
++ rc = ecryptfs_init_crypt_ctx(crypt_stat);
++ if (rc)
++ goto out_free;
+ if (unlikely(data[(*packet_size)++] != 0x03)) {
+ printk(KERN_WARNING "Only S2K ID 3 is currently supported\n");
+ rc = -ENOSYS;
+diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
+index c6d7a4d..e14cf7e 100644
+--- a/fs/ecryptfs/kthread.c
++++ b/fs/ecryptfs/kthread.c
+@@ -136,6 +136,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
+ const struct cred *cred)
+ {
+ struct ecryptfs_open_req *req;
++ int flags = O_LARGEFILE;
+ int rc = 0;
+
+ /* Corresponding dput() and mntput() are done when the
+@@ -143,10 +144,14 @@ int ecryptfs_privileged_open(struct file **lower_file,
+ * destroyed. */
+ dget(lower_dentry);
+ mntget(lower_mnt);
+- (*lower_file) = dentry_open(lower_dentry, lower_mnt,
+- (O_RDWR | O_LARGEFILE), cred);
++ flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
++ (*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred);
+ if (!IS_ERR(*lower_file))
+ goto out;
++ if (flags & O_RDONLY) {
++ rc = PTR_ERR((*lower_file));
++ goto out;
++ }
+ req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
+ if (!req) {
+ rc = -ENOMEM;
+@@ -180,21 +185,8 @@ int ecryptfs_privileged_open(struct file **lower_file,
+ __func__);
+ goto out_unlock;
+ }
+- if (IS_ERR(*req->lower_file)) {
++ if (IS_ERR(*req->lower_file))
+ rc = PTR_ERR(*req->lower_file);
+- dget(lower_dentry);
+- mntget(lower_mnt);
+- (*lower_file) = dentry_open(lower_dentry, lower_mnt,
+- (O_RDONLY | O_LARGEFILE), cred);
+- if (IS_ERR(*lower_file)) {
+- rc = PTR_ERR(*req->lower_file);
+- (*lower_file) = NULL;
+- printk(KERN_WARNING "%s: Error attempting privileged "
+- "open of lower file with either RW or RO "
+- "perms; rc = [%d]. Giving up.\n",
+- __func__, rc);
+- }
+- }
+ out_unlock:
+ mutex_unlock(&req->mux);
+ out_free:
+diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
+index 9f0aa98..101fe4c 100644
+--- a/fs/ecryptfs/main.c
++++ b/fs/ecryptfs/main.c
+@@ -129,11 +129,10 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
+ lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+ rc = ecryptfs_privileged_open(&inode_info->lower_file,
+ lower_dentry, lower_mnt, cred);
+- if (rc || IS_ERR(inode_info->lower_file)) {
++ if (rc) {
+ printk(KERN_ERR "Error opening lower persistent file "
+ "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
+ "rc = [%d]\n", lower_dentry, lower_mnt, rc);
+- rc = PTR_ERR(inode_info->lower_file);
+ inode_info->lower_file = NULL;
+ }
+ }
+diff --git a/fs/inode.c b/fs/inode.c
+index ae7b67e..1a959c0 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -697,13 +697,15 @@ void unlock_new_inode(struct inode *inode)
+ }
+ #endif
+ /*
+- * This is special! We do not need the spinlock
+- * when clearing I_LOCK, because we're guaranteed
+- * that nobody else tries to do anything about the
+- * state of the inode when it is locked, as we
+- * just created it (so there can be no old holders
+- * that haven't tested I_LOCK).
++ * This is special! We do not need the spinlock when clearing I_LOCK,
++ * because we're guaranteed that nobody else tries to do anything about
++ * the state of the inode when it is locked, as we just created it (so
++ * there can be no old holders that haven't tested I_LOCK).
++ * However we must emit the memory barrier so that other CPUs reliably
++ * see the clearing of I_LOCK after the other inode initialisation has
++ * completed.
+ */
++ smp_mb();
+ WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW));
+ inode->i_state &= ~(I_LOCK|I_NEW);
+ wake_up_inode(inode);
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 3fd23f7..bf9b470 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -444,6 +444,7 @@ static struct rpc_cred *lookup_cb_cred(struct nfs4_cb_conn *cb)
+ struct auth_cred acred = {
+ .machine_cred = 1
+ };
++ struct rpc_auth *auth = cb->cb_client->cl_auth;
+
+ /*
+ * Note in the gss case this doesn't actually have to wait for a
+@@ -451,8 +452,7 @@ static struct rpc_cred *lookup_cb_cred(struct nfs4_cb_conn *cb)
+ * non-uptodate cred which the rpc state machine will fill in with
+ * a refresh_upcall later.
+ */
+- return rpcauth_lookup_credcache(cb->cb_client->cl_auth, &acred,
+- RPCAUTH_LOOKUP_NEW);
++ return auth->au_ops->lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
+ }
+
+ void do_probe_callback(struct nfs4_client *clp)
+diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
+index c668bca..5be2c8b 100644
+--- a/fs/nilfs2/btnode.c
++++ b/fs/nilfs2/btnode.c
+@@ -36,6 +36,7 @@
+
+ void nilfs_btnode_cache_init_once(struct address_space *btnc)
+ {
++ memset(btnc, 0, sizeof(*btnc));
+ INIT_RADIX_TREE(&btnc->page_tree, GFP_ATOMIC);
+ spin_lock_init(&btnc->tree_lock);
+ INIT_LIST_HEAD(&btnc->private_list);
+diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
+index 59b43a0..5fd7d2b 100644
+--- a/fs/proc/kcore.c
++++ b/fs/proc/kcore.c
+@@ -361,7 +361,13 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
+ /* don't dump ioremap'd stuff! (TA) */
+ if (m->flags & VM_IOREMAP)
+ continue;
+- memcpy(elf_buf + (vmstart - start),
++ /*
++ * we may access memory holes, then use
++ * ex_table. checking return value just for
++ * avoid warnings.
++ */
++ vmsize = __copy_from_user_inatomic(
++ elf_buf + (vmstart - start),
+ (char *)vmstart, vmsize);
+ }
+ read_unlock(&vmlist_lock);
+diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
+index 0c10a0b..766b1d4 100644
+--- a/fs/proc/uptime.c
++++ b/fs/proc/uptime.c
+@@ -4,13 +4,18 @@
+ #include <linux/sched.h>
+ #include <linux/seq_file.h>
+ #include <linux/time.h>
++#include <linux/kernel_stat.h>
+ #include <asm/cputime.h>
+
+ static int uptime_proc_show(struct seq_file *m, void *v)
+ {
+ struct timespec uptime;
+ struct timespec idle;
+- cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
++ int i;
++ cputime_t idletime = cputime_zero;
++
++ for_each_possible_cpu(i)
++ idletime = cputime64_add(idletime, kstat_cpu(i).cpustat.idle);
+
+ do_posix_clock_monotonic_gettime(&uptime);
+ monotonic_to_bootbased(&uptime);
+diff --git a/include/linux/tty.h b/include/linux/tty.h
+index e8c6c91..b982a17 100644
+--- a/include/linux/tty.h
++++ b/include/linux/tty.h
+@@ -185,7 +185,12 @@ struct tty_port;
+ struct tty_port_operations {
+ /* Return 1 if the carrier is raised */
+ int (*carrier_raised)(struct tty_port *port);
++ /* Control the DTR line */
+ void (*dtr_rts)(struct tty_port *port, int raise);
++ /* Called when the last close completes or a hangup finishes
++ IFF the port was initialized. Do not use to free resources */
++ void (*shutdown)(struct tty_port *port);
++ void (*drop)(struct tty_port *port);
+ };
+
+ struct tty_port {
+@@ -457,7 +462,8 @@ extern int tty_port_block_til_ready(struct tty_port *port,
+ extern int tty_port_close_start(struct tty_port *port,
+ struct tty_struct *tty, struct file *filp);
+ extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
+-
++extern void tty_port_close(struct tty_port *port,
++ struct tty_struct *tty, struct file *filp);
+ extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
+ extern int tty_unregister_ldisc(int disc);
+ extern int tty_set_ldisc(struct tty_struct *tty, int ldisc);
+diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
+index 0ec50ba..73f121e 100644
+--- a/include/linux/usb/serial.h
++++ b/include/linux/usb/serial.h
+@@ -261,6 +261,9 @@ struct usb_serial_driver {
+ be an attached tty at this point */
+ void (*dtr_rts)(struct usb_serial_port *port, int on);
+ int (*carrier_raised)(struct usb_serial_port *port);
++ /* Called by the usb serial hooks to allow the user to rework the
++ termios state */
++ void (*init_termios)(struct tty_struct *tty);
+ /* USB events */
+ void (*read_int_callback)(struct urb *urb);
+ void (*write_int_callback)(struct urb *urb);
+diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
+index 9b4ac93..56677eb 100644
+--- a/include/pcmcia/ss.h
++++ b/include/pcmcia/ss.h
+@@ -279,7 +279,7 @@ extern struct pccard_resource_ops pccard_iodyn_ops;
+ extern struct pccard_resource_ops pccard_nonstatic_ops;
+
+ /* socket drivers are expected to use these callbacks in their .drv struct */
+-extern int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state);
++extern int pcmcia_socket_dev_suspend(struct device *dev);
+ extern int pcmcia_socket_dev_resume(struct device *dev);
+
+ /* socket drivers use this callback in their IRQ handler */
+diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
+index 3f49f53..b1dc468 100644
+--- a/kernel/perf_counter.c
++++ b/kernel/perf_counter.c
+@@ -4143,8 +4143,8 @@ done:
+ static int perf_copy_attr(struct perf_counter_attr __user *uattr,
+ struct perf_counter_attr *attr)
+ {
+- int ret;
+ u32 size;
++ int ret;
+
+ if (!access_ok(VERIFY_WRITE, uattr, PERF_ATTR_SIZE_VER0))
+ return -EFAULT;
+@@ -4169,19 +4169,19 @@ static int perf_copy_attr(struct perf_counter_attr __user *uattr,
+
+ /*
+ * If we're handed a bigger struct than we know of,
+- * ensure all the unknown bits are 0.
++ * ensure all the unknown bits are 0 - i.e. new
++ * user-space does not rely on any kernel feature
++ * extensions we dont know about yet.
+ */
+ if (size > sizeof(*attr)) {
+- unsigned long val;
+- unsigned long __user *addr;
+- unsigned long __user *end;
++ unsigned char __user *addr;
++ unsigned char __user *end;
++ unsigned char val;
+
+- addr = PTR_ALIGN((void __user *)uattr + sizeof(*attr),
+- sizeof(unsigned long));
+- end = PTR_ALIGN((void __user *)uattr + size,
+- sizeof(unsigned long));
++ addr = (void __user *)uattr + sizeof(*attr);
++ end = (void __user *)uattr + size;
+
+- for (; addr < end; addr += sizeof(unsigned long)) {
++ for (; addr < end; addr++) {
+ ret = get_user(val, addr);
+ if (ret)
+ return ret;
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index cafdcee..cae0337 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1010,6 +1010,7 @@ int __weak alloc_bootmem_huge_page(struct hstate *h)
+ NODE_DATA(h->hugetlb_next_nid),
+ huge_page_size(h), huge_page_size(h), 0);
+
++ hstate_next_node(h);
+ if (addr) {
+ /*
+ * Use the beginning of the huge page to store the
+@@ -1019,7 +1020,6 @@ int __weak alloc_bootmem_huge_page(struct hstate *h)
+ m = addr;
+ goto found;
+ }
+- hstate_next_node(h);
+ nr_nodes--;
+ }
+ return 0;
+diff --git a/mm/memory.c b/mm/memory.c
+index aede2ce..753b2e6 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2638,7 +2638,8 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ goto oom_free_page;
+
+ entry = mk_pte(page, vma->vm_page_prot);
+- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
++ if (vma->vm_flags & VM_WRITE)
++ entry = pte_mkwrite(pte_mkdirty(entry));
+
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (!pte_none(*page_table))
+diff --git a/mm/mlock.c b/mm/mlock.c
+index 45eb650..e13918d 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -139,49 +139,36 @@ static void munlock_vma_page(struct page *page)
+ }
+
+ /**
+- * __mlock_vma_pages_range() - mlock/munlock a range of pages in the vma.
++ * __mlock_vma_pages_range() - mlock a range of pages in the vma.
+ * @vma: target vma
+ * @start: start address
+ * @end: end address
+- * @mlock: 0 indicate munlock, otherwise mlock.
+ *
+- * If @mlock == 0, unlock an mlocked range;
+- * else mlock the range of pages. This takes care of making the pages present ,
+- * too.
++ * This takes care of making the pages present too.
+ *
+ * return 0 on success, negative error code on error.
+ *
+ * vma->vm_mm->mmap_sem must be held for at least read.
+ */
+ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
+- unsigned long start, unsigned long end,
+- int mlock)
++ unsigned long start, unsigned long end)
+ {
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long addr = start;
+ struct page *pages[16]; /* 16 gives a reasonable batch */
+ int nr_pages = (end - start) / PAGE_SIZE;
+ int ret = 0;
+- int gup_flags = 0;
++ int gup_flags;
+
+ VM_BUG_ON(start & ~PAGE_MASK);
+ VM_BUG_ON(end & ~PAGE_MASK);
+ VM_BUG_ON(start < vma->vm_start);
+ VM_BUG_ON(end > vma->vm_end);
+- VM_BUG_ON((!rwsem_is_locked(&mm->mmap_sem)) &&
+- (atomic_read(&mm->mm_users) != 0));
+-
+- /*
+- * mlock: don't page populate if vma has PROT_NONE permission.
+- * munlock: always do munlock although the vma has PROT_NONE
+- * permission, or SIGKILL is pending.
+- */
+- if (!mlock)
+- gup_flags |= GUP_FLAGS_IGNORE_VMA_PERMISSIONS |
+- GUP_FLAGS_IGNORE_SIGKILL;
++ VM_BUG_ON(!rwsem_is_locked(&mm->mmap_sem));
+
++ gup_flags = 0;
+ if (vma->vm_flags & VM_WRITE)
+- gup_flags |= GUP_FLAGS_WRITE;
++ gup_flags = GUP_FLAGS_WRITE;
+
+ while (nr_pages > 0) {
+ int i;
+@@ -201,19 +188,10 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
+ * This can happen for, e.g., VM_NONLINEAR regions before
+ * a page has been allocated and mapped at a given offset,
+ * or for addresses that map beyond end of a file.
+- * We'll mlock the the pages if/when they get faulted in.
++ * We'll mlock the pages if/when they get faulted in.
+ */
+ if (ret < 0)
+ break;
+- if (ret == 0) {
+- /*
+- * We know the vma is there, so the only time
+- * we cannot get a single page should be an
+- * error (ret < 0) case.
+- */
+- WARN_ON(1);
+- break;
+- }
+
+ lru_add_drain(); /* push cached pages to LRU */
+
+@@ -224,28 +202,22 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
+ /*
+ * Because we lock page here and migration is blocked
+ * by the elevated reference, we need only check for
+- * page truncation (file-cache only).
++ * file-cache page truncation. This page->mapping
++ * check also neatly skips over the ZERO_PAGE(),
++ * though if that's common we'd prefer not to lock it.
+ */
+- if (page->mapping) {
+- if (mlock)
+- mlock_vma_page(page);
+- else
+- munlock_vma_page(page);
+- }
++ if (page->mapping)
++ mlock_vma_page(page);
+ unlock_page(page);
+- put_page(page); /* ref from get_user_pages() */
+-
+- /*
+- * here we assume that get_user_pages() has given us
+- * a list of virtually contiguous pages.
+- */
+- addr += PAGE_SIZE; /* for next get_user_pages() */
+- nr_pages--;
++ put_page(page); /* ref from get_user_pages() */
+ }
++
++ addr += ret * PAGE_SIZE;
++ nr_pages -= ret;
+ ret = 0;
+ }
+
+- return ret; /* count entire vma as locked_vm */
++ return ret; /* 0 or negative error code */
+ }
+
+ /*
+@@ -289,7 +261,7 @@ long mlock_vma_pages_range(struct vm_area_struct *vma,
+ is_vm_hugetlb_page(vma) ||
+ vma == get_gate_vma(current))) {
+
+- __mlock_vma_pages_range(vma, start, end, 1);
++ __mlock_vma_pages_range(vma, start, end);
+
+ /* Hide errors from mmap() and other callers */
+ return 0;
+@@ -310,7 +282,6 @@ no_mlock:
+ return nr_pages; /* error or pages NOT mlocked */
+ }
+
+-
+ /*
+ * munlock_vma_pages_range() - munlock all pages in the vma range.'
+ * @vma - vma containing range to be munlock()ed.
+@@ -330,10 +301,24 @@ no_mlock:
+ * free them. This will result in freeing mlocked pages.
+ */
+ void munlock_vma_pages_range(struct vm_area_struct *vma,
+- unsigned long start, unsigned long end)
++ unsigned long start, unsigned long end)
+ {
++ unsigned long addr;
++
++ lru_add_drain();
+ vma->vm_flags &= ~VM_LOCKED;
+- __mlock_vma_pages_range(vma, start, end, 0);
++
++ for (addr = start; addr < end; addr += PAGE_SIZE) {
++ struct page *page = follow_page(vma, addr, FOLL_GET);
++ if (page) {
++ lock_page(page);
++ if (page->mapping)
++ munlock_vma_page(page);
++ unlock_page(page);
++ put_page(page);
++ }
++ cond_resched();
++ }
+ }
+
+ /*
+@@ -400,18 +385,14 @@ success:
+ * It's okay if try_to_unmap_one unmaps a page just after we
+ * set VM_LOCKED, __mlock_vma_pages_range will bring it back.
+ */
+- vma->vm_flags = newflags;
+
+ if (lock) {
+- ret = __mlock_vma_pages_range(vma, start, end, 1);
+-
+- if (ret > 0) {
+- mm->locked_vm -= ret;
+- ret = 0;
+- } else
+- ret = __mlock_posix_error_return(ret); /* translate if needed */
++ vma->vm_flags = newflags;
++ ret = __mlock_vma_pages_range(vma, start, end);
++ if (ret < 0)
++ ret = __mlock_posix_error_return(ret);
+ } else {
+- __mlock_vma_pages_range(vma, start, end, 0);
++ munlock_vma_pages_range(vma, start, end);
+ }
+
+ out:
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 8101de4..cbb7cb3 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -570,9 +570,9 @@ again: remove_next = 1 + (end > next->vm_end);
+
+ /*
+ * When changing only vma->vm_end, we don't really need
+- * anon_vma lock: but is that case worth optimizing out?
++ * anon_vma lock.
+ */
+- if (vma->anon_vma)
++ if (vma->anon_vma && (insert || importer || start != vma->vm_start))
+ anon_vma = vma->anon_vma;
+ if (anon_vma) {
+ spin_lock(&anon_vma->lock);
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 66e81e7..82fedca 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -1056,7 +1056,7 @@ static int do_mmap_shared_file(struct vm_area_struct *vma)
+ ret = vma->vm_file->f_op->mmap(vma->vm_file, vma);
+ if (ret == 0) {
+ vma->vm_region->vm_top = vma->vm_region->vm_end;
+- return ret;
++ return 0;
+ }
+ if (ret != -ENOSYS)
+ return ret;
+@@ -1073,7 +1073,8 @@ static int do_mmap_shared_file(struct vm_area_struct *vma)
+ */
+ static int do_mmap_private(struct vm_area_struct *vma,
+ struct vm_region *region,
+- unsigned long len)
++ unsigned long len,
++ unsigned long capabilities)
+ {
+ struct page *pages;
+ unsigned long total, point, n, rlen;
+@@ -1084,13 +1085,13 @@ static int do_mmap_private(struct vm_area_struct *vma,
+ * shared mappings on devices or memory
+ * - VM_MAYSHARE will be set if it may attempt to share
+ */
+- if (vma->vm_file) {
++ if (capabilities & BDI_CAP_MAP_DIRECT) {
+ ret = vma->vm_file->f_op->mmap(vma->vm_file, vma);
+ if (ret == 0) {
+ /* shouldn't return success if we're not sharing */
+ BUG_ON(!(vma->vm_flags & VM_MAYSHARE));
+ vma->vm_region->vm_top = vma->vm_region->vm_end;
+- return ret;
++ return 0;
+ }
+ if (ret != -ENOSYS)
+ return ret;
+@@ -1328,7 +1329,7 @@ unsigned long do_mmap_pgoff(struct file *file,
+ * - this is the hook for quasi-memory character devices to
+ * tell us the location of a shared mapping
+ */
+- if (file && file->f_op->get_unmapped_area) {
++ if (capabilities & BDI_CAP_MAP_DIRECT) {
+ addr = file->f_op->get_unmapped_area(file, addr, len,
+ pgoff, flags);
+ if (IS_ERR((void *) addr)) {
+@@ -1352,15 +1353,17 @@ unsigned long do_mmap_pgoff(struct file *file,
+ }
+
+ vma->vm_region = region;
+- add_nommu_region(region);
+
+- /* set up the mapping */
++ /* set up the mapping
++ * - the region is filled in if BDI_CAP_MAP_DIRECT is still set
++ */
+ if (file && vma->vm_flags & VM_SHARED)
+ ret = do_mmap_shared_file(vma);
+ else
+- ret = do_mmap_private(vma, region, len);
++ ret = do_mmap_private(vma, region, len, capabilities);
+ if (ret < 0)
+- goto error_put_region;
++ goto error_just_free;
++ add_nommu_region(region);
+
+ /* okay... we have a mapping; now we have to register it */
+ result = vma->vm_start;
+@@ -1378,19 +1381,6 @@ share:
+ kleave(" = %lx", result);
+ return result;
+
+-error_put_region:
+- __put_nommu_region(region);
+- if (vma) {
+- if (vma->vm_file) {
+- fput(vma->vm_file);
+- if (vma->vm_flags & VM_EXECUTABLE)
+- removed_exe_file_vma(vma->vm_mm);
+- }
+- kmem_cache_free(vm_area_cachep, vma);
+- }
+- kleave(" = %d [pr]", ret);
+- return ret;
+-
+ error_just_free:
+ up_write(&nommu_region_sem);
+ error:
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index a0de15f..0b3c6cb 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2783,7 +2783,8 @@ static void setup_zone_migrate_reserve(struct zone *zone)
+ {
+ unsigned long start_pfn, pfn, end_pfn;
+ struct page *page;
+- unsigned long reserve, block_migratetype;
++ unsigned long block_migratetype;
++ int reserve;
+
+ /* Get the start pfn, end pfn and the number of blocks to reserve */
+ start_pfn = zone->zone_start_pfn;
+@@ -2791,6 +2792,15 @@ static void setup_zone_migrate_reserve(struct zone *zone)
+ reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >>
+ pageblock_order;
+
++ /*
++ * Reserve blocks are generally in place to help high-order atomic
++ * allocations that are short-lived. A min_free_kbytes value that
++ * would result in more than 2 reserve blocks for atomic allocations
++ * is assumed to be in place to help anti-fragmentation for the
++ * future allocation of hugepages at runtime.
++ */
++ reserve = min(2, reserve);
++
+ for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
+ if (!pfn_valid(pfn))
+ continue;
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index da0f64f..f03529c 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -538,7 +538,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
+ if (level != SOL_AX25)
+ return -ENOPROTOOPT;
+
+- if (optlen < sizeof(int))
++ if (optlen < (int)sizeof(int))
+ return -EINVAL;
+
+ if (get_user(opt, (int __user *)optval))
+diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
+index d22f611..991fe40 100644
+--- a/net/bridge/br_netfilter.c
++++ b/net/bridge/br_netfilter.c
+@@ -359,7 +359,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
+ },
+ .proto = 0,
+ };
+- struct in_device *in_dev = in_dev_get(dev);
++ struct in_device *in_dev = __in_dev_get_rcu(dev);
+
+ /* If err equals -EHOSTUNREACH the error is due to a
+ * martian destination or due to the fact that
+diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
+index 133eeae..ce50688 100644
+--- a/net/bridge/netfilter/ebt_ulog.c
++++ b/net/bridge/netfilter/ebt_ulog.c
+@@ -266,7 +266,7 @@ static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
+ if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
+ uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
+
+- return 0;
++ return true;
+ }
+
+ static struct xt_target ebt_ulog_tg_reg __read_mostly = {
+diff --git a/net/can/af_can.c b/net/can/af_can.c
+index e733725..264c968 100644
+--- a/net/can/af_can.c
++++ b/net/can/af_can.c
+@@ -199,6 +199,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
+ * @skb: pointer to socket buffer with CAN frame in data section
+ * @loop: loopback for listeners on local CAN sockets (recommended default!)
+ *
++ * Due to the loopback this routine must not be called from hardirq context.
++ *
+ * Return:
+ * 0 on success
+ * -ENETDOWN when the selected interface is down
+@@ -278,7 +280,7 @@ int can_send(struct sk_buff *skb, int loop)
+ }
+
+ if (newskb)
+- netif_rx(newskb);
++ netif_rx_ni(newskb);
+
+ /* update statistics */
+ can_stats.tx_frames++;
+diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
+index 3229e0a..b6ddd56 100644
+--- a/net/ipv4/netfilter/nf_nat_core.c
++++ b/net/ipv4/netfilter/nf_nat_core.c
+@@ -212,7 +212,7 @@ find_best_ips_proto(struct nf_conntrack_tuple *tuple,
+ maxip = ntohl(range->max_ip);
+ j = jhash_2words((__force u32)tuple->src.u3.ip,
+ range->flags & IP_NAT_RANGE_PERSISTENT ?
+- (__force u32)tuple->dst.u3.ip : 0, 0);
++ 0 : (__force u32)tuple->dst.u3.ip, 0);
+ j = ((u64)j * (maxip - minip + 1)) >> 32;
+ *var_ipp = htonl(minip + j);
+ }
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index b5869b9..b8614c6 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1089,14 +1089,14 @@ void nf_conntrack_flush_report(struct net *net, u32 pid, int report)
+ }
+ EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
+
+-static void nf_ct_release_dying_list(void)
++static void nf_ct_release_dying_list(struct net *net)
+ {
+ struct nf_conntrack_tuple_hash *h;
+ struct nf_conn *ct;
+ struct hlist_nulls_node *n;
+
+ spin_lock_bh(&nf_conntrack_lock);
+- hlist_nulls_for_each_entry(h, n, &init_net.ct.dying, hnnode) {
++ hlist_nulls_for_each_entry(h, n, &net->ct.dying, hnnode) {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ /* never fails to remove them, no listeners at this point */
+ nf_ct_kill(ct);
+@@ -1115,7 +1115,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
+ {
+ i_see_dead_people:
+ nf_ct_iterate_cleanup(net, kill_all, NULL);
+- nf_ct_release_dying_list();
++ nf_ct_release_dying_list(net);
+ if (atomic_read(&net->ct.count) != 0) {
+ schedule();
+ goto i_see_dead_people;
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index ebe5718..f9f7177 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1836,7 +1836,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
+ static int packet_getsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int __user *optlen)
+ {
+- int len;
++ unsigned int len;
+ int val;
+ struct sock *sk = sock->sk;
+ struct packet_sock *po = pkt_sk(sk);
+@@ -1849,7 +1849,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
+ if (get_user(len, optlen))
+ return -EFAULT;
+
+- if (len < 0)
++ if ((int)len < 0)
+ return -EINVAL;
+
+ switch (optname) {
+diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
+index c29be8f..43300b3 100644
+--- a/scripts/Kbuild.include
++++ b/scripts/Kbuild.include
+@@ -105,12 +105,12 @@ as-instr = $(call try-run,\
+ # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
+
+ cc-option = $(call try-run,\
+- $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2))
++ $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2))
+
+ # cc-option-yn
+ # Usage: flag := $(call cc-option-yn,-march=winchip-c6)
+ cc-option-yn = $(call try-run,\
+- $(CC) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n)
++ $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n)
+
+ # cc-option-align
+ # Prefix align with either -falign or -malign
+diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
+index 64343cc..86c3896 100644
+--- a/scripts/kallsyms.c
++++ b/scripts/kallsyms.c
+@@ -585,7 +585,7 @@ static int prefix_underscores_count(const char *str)
+ {
+ const char *tail = str;
+
+- while (*tail != '_')
++ while (*tail == '_')
+ tail++;
+
+ return tail - str;
+diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
+index 5e17de9..5010952 100644
+--- a/tools/perf/builtin-annotate.c
++++ b/tools/perf/builtin-annotate.c
+@@ -1335,8 +1335,8 @@ static int __cmd_annotate(void)
+ exit(-1);
+ }
+
+- if (!force && (stat.st_uid != geteuid())) {
+- fprintf(stderr, "file: %s not owned by current user\n", input_name);
++ if (!force && stat.st_uid && (stat.st_uid != geteuid())) {
++ fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
+ exit(-1);
+ }
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index 8b2ec88..b8a75f6 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -1857,8 +1857,8 @@ static int __cmd_report(void)
+ exit(-1);
+ }
+
+- if (!force && (stat.st_uid != geteuid())) {
+- fprintf(stderr, "file: %s not owned by current user\n", input_name);
++ if (!force && stat.st_uid && (stat.st_uid != geteuid())) {
++ fprintf(stderr, "file: %s not owned by current user or root\n", input_name);
+ exit(-1);
+ }
+
+diff --git a/tools/perf/util/module.c b/tools/perf/util/module.c
+index ddabe92..702083d 100644
+--- a/tools/perf/util/module.c
++++ b/tools/perf/util/module.c
+@@ -422,7 +422,7 @@ static int mod_dso__load_module_paths(struct mod_dso *self)
+ len += strlen(uts.release);
+ len += strlen("/modules.dep");
+
+- path = calloc(1, len);
++ path = calloc(1, len + 1);
+ if (path == NULL)
+ goto out_failure;
+
Modified: dists/trunk/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/base Mon Oct 5 03:18:36 2009 (r14338)
+++ dists/trunk/linux-2.6/debian/patches/series/base Mon Oct 5 21:55:43 2009 (r14339)
@@ -38,3 +38,5 @@
+ bugfix/x86/fix-i8xx-agp-flush.patch
+ bugfix/all/stable/2.6.31.1.patch
+ bugfix/all/fs-nfs-avoid-overrun-copying-client-ip.patch
+- bugfix/x86/fix-i8xx-agp-flush.patch
++ bugfix/all/stable/2.6.31.2.patch
More information about the Kernel-svn-changes
mailing list