From 1096aa1bacbf12e70aa021cde25fd315324c7c07 Mon Sep 17 00:00:00 2001 From: Maximilian Attems Date: Mon, 5 Oct 2009 21:55:43 +0000 Subject: [PATCH] add stable 2.6.31.2 svn path=/dists/trunk/linux-2.6/; revision=14339 --- debian/changelog | 3 + .../patches/bugfix/all/stable/2.6.31.2.patch | 7459 +++++++++++++++++ debian/patches/series/base | 2 + 3 files changed, 7464 insertions(+) create mode 100644 debian/patches/bugfix/all/stable/2.6.31.2.patch diff --git a/debian/changelog b/debian/changelog index df9ed963c..24b4d0aa2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,9 @@ linux-2.6 (2.6.31-1~experimental.2) UNRELEASED; urgency=low (Closes: #549002) * Add support for DEB_BUILD_OPTIONS=parallel=N (Closes: #458560) + [ maximilian attems ] + * Add stable release 2.6.31.2. + -- Ben Hutchings Sun, 04 Oct 2009 19:48:35 +0100 linux-2.6 (2.6.31-1~experimental.1) experimental; urgency=low diff --git a/debian/patches/bugfix/all/stable/2.6.31.2.patch b/debian/patches/bugfix/all/stable/2.6.31.2.patch new file mode 100644 index 000000000..05496ef55 --- /dev/null +++ b/debian/patches/bugfix/all/stable/2.6.31.2.patch @@ -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 ++L: lm-sensors@lm-sensors.org ++S: Maintained ++F: drivers/hwmon/asus_atk0110.c ++ + ATI_REMOTE2 DRIVER + M: Ville Syrjala + 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 + #include + ++#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 + #include + #include ++#include ++ ++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 + #include + #include ++#include + + #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@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@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@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.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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include ++#include + + #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 + #include + #include ++#include + #include + #include + +@@ -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@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 + #include + #include ++#include + #include + + 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; + diff --git a/debian/patches/series/base b/debian/patches/series/base index 5296dcf9c..cc7695fa1 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -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