From 6482fa4ba90a7583eb300149ad0d4e7cadac2ee5 Mon Sep 17 00:00:00 2001 From: Tobias Powalowski Date: Tue, 22 Mar 2011 15:20:43 +0100 Subject: add new pre patches --- PATCHCFG | 3 +- patches/2.6.38.1-pre.patch | 5048 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 5050 insertions(+), 1 deletion(-) create mode 100644 patches/2.6.38.1-pre.patch diff --git a/PATCHCFG b/PATCHCFG index 3c020a0..4edfa26 100644 --- a/PATCHCFG +++ b/PATCHCFG @@ -14,6 +14,7 @@ PATCHES=( # add latest fixes from stable queue, if needed # http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git + 2.6.38.1-pre.patch%1 # fix #19234 i1915 display size fix-i915.patch%1 @@ -24,7 +25,7 @@ PATCHES=( aufs2-standalone-20110314.patch%1 ) # Name of the resulting patch (will be bzipped afterwards) -PATCHNAME="patch-2.6.38-1-ARCH" +PATCHNAME="patch-2.6.38-2-ARCH" # Run this before applying patches pre_apply() { diff --git a/patches/2.6.38.1-pre.patch b/patches/2.6.38.1-pre.patch new file mode 100644 index 0000000..42c153b --- /dev/null +++ b/patches/2.6.38.1-pre.patch @@ -0,0 +1,5048 @@ +From c826cb7dfce80512c26c984350077a25046bd215 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Tue, 15 Mar 2011 15:29:21 -0700 +Subject: dcache.c: create helper function for duplicated functionality + +From: Linus Torvalds + +commit c826cb7dfce80512c26c984350077a25046bd215 upstream. + +This creates a helper function for he "try to ascend into the parent +directory" case, which was written out in triplicate before. With all +the locking and subtle sequence number stuff, we really don't want to +duplicate that kind of code. + +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/dcache.c | 88 +++++++++++++++++++++++++----------------------------------- + 1 file changed, 37 insertions(+), 51 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1012,6 +1012,34 @@ void shrink_dcache_for_umount(struct sup + } + + /* ++ * This tries to ascend one level of parenthood, but ++ * we can race with renaming, so we need to re-check ++ * the parenthood after dropping the lock and check ++ * that the sequence number still matches. ++ */ ++static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq) ++{ ++ struct dentry *new = old->d_parent; ++ ++ rcu_read_lock(); ++ spin_unlock(&old->d_lock); ++ spin_lock(&new->d_lock); ++ ++ /* ++ * might go back up the wrong parent if we have had a rename ++ * or deletion ++ */ ++ if (new != old->d_parent || ++ (!locked && read_seqretry(&rename_lock, seq))) { ++ spin_unlock(&new->d_lock); ++ new = NULL; ++ } ++ rcu_read_unlock(); ++ return new; ++} ++ ++ ++/* + * Search for at least 1 mount point in the dentry's subdirs. + * We descend to the next level whenever the d_subdirs + * list is non-empty and continue searching. +@@ -1066,24 +1094,10 @@ resume: + * All done at this level ... ascend and resume the search. + */ + if (this_parent != parent) { +- struct dentry *tmp; +- struct dentry *child; +- +- tmp = this_parent->d_parent; +- rcu_read_lock(); +- spin_unlock(&this_parent->d_lock); +- child = this_parent; +- this_parent = tmp; +- spin_lock(&this_parent->d_lock); +- /* might go back up the wrong parent if we have had a rename +- * or deletion */ +- if (this_parent != child->d_parent || +- (!locked && read_seqretry(&rename_lock, seq))) { +- spin_unlock(&this_parent->d_lock); +- rcu_read_unlock(); ++ struct dentry *child = this_parent; ++ this_parent = try_to_ascend(this_parent, locked, seq); ++ if (!this_parent) + goto rename_retry; +- } +- rcu_read_unlock(); + next = child->d_u.d_child.next; + goto resume; + } +@@ -1181,24 +1195,10 @@ resume: + * All done at this level ... ascend and resume the search. + */ + if (this_parent != parent) { +- struct dentry *tmp; +- struct dentry *child; +- +- tmp = this_parent->d_parent; +- rcu_read_lock(); +- spin_unlock(&this_parent->d_lock); +- child = this_parent; +- this_parent = tmp; +- spin_lock(&this_parent->d_lock); +- /* might go back up the wrong parent if we have had a rename +- * or deletion */ +- if (this_parent != child->d_parent || +- (!locked && read_seqretry(&rename_lock, seq))) { +- spin_unlock(&this_parent->d_lock); +- rcu_read_unlock(); ++ struct dentry *child = this_parent; ++ this_parent = try_to_ascend(this_parent, locked, seq); ++ if (!this_parent) + goto rename_retry; +- } +- rcu_read_unlock(); + next = child->d_u.d_child.next; + goto resume; + } +@@ -2942,28 +2942,14 @@ resume: + spin_unlock(&dentry->d_lock); + } + if (this_parent != root) { +- struct dentry *tmp; +- struct dentry *child; +- +- tmp = this_parent->d_parent; ++ struct dentry *child = this_parent; + if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { + this_parent->d_flags |= DCACHE_GENOCIDE; + this_parent->d_count--; + } +- rcu_read_lock(); +- spin_unlock(&this_parent->d_lock); +- child = this_parent; +- this_parent = tmp; +- spin_lock(&this_parent->d_lock); +- /* might go back up the wrong parent if we have had a rename +- * or deletion */ +- if (this_parent != child->d_parent || +- (!locked && read_seqretry(&rename_lock, seq))) { +- spin_unlock(&this_parent->d_lock); +- rcu_read_unlock(); ++ this_parent = try_to_ascend(this_parent, locked, seq); ++ if (!this_parent) + goto rename_retry; +- } +- rcu_read_unlock(); + next = child->d_u.d_child.next; + goto resume; + } +From c83ce989cb5ff86575821992ea82c4df5c388ebc Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Tue, 15 Mar 2011 13:36:43 -0400 +Subject: VFS: Fix the nfs sillyrename regression in kernel 2.6.38 + +From: Trond Myklebust + +commit c83ce989cb5ff86575821992ea82c4df5c388ebc upstream. + +The new vfs locking scheme introduced in 2.6.38 breaks NFS sillyrename +because the latter relies on being able to determine the parent +directory of the dentry in the ->iput() callback in order to send the +appropriate unlink rpc call. + +Looking at the code that cares about races with dput(), there doesn't +seem to be anything that specifically uses d_parent as a test for +whether or not there is a race: + - __d_lookup_rcu(), __d_lookup() all test for d_hashed() after d_parent + - shrink_dcache_for_umount() is safe since nothing else can rearrange + the dentries in that super block. + - have_submount(), select_parent() and d_genocide() can test for a + deletion if we set the DCACHE_DISCONNECTED flag when the dentry + is removed from the parent's d_subdirs list. + +Signed-off-by: Trond Myklebust +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/dcache.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -296,8 +296,12 @@ static struct dentry *d_kill(struct dent + __releases(parent->d_lock) + __releases(dentry->d_inode->i_lock) + { +- dentry->d_parent = NULL; + list_del(&dentry->d_u.d_child); ++ /* ++ * Inform try_to_ascend() that we are no longer attached to the ++ * dentry tree ++ */ ++ dentry->d_flags |= DCACHE_DISCONNECTED; + if (parent) + spin_unlock(&parent->d_lock); + dentry_iput(dentry); +@@ -1030,6 +1034,7 @@ static struct dentry *try_to_ascend(stru + * or deletion + */ + if (new != old->d_parent || ++ (old->d_flags & DCACHE_DISCONNECTED) || + (!locked && read_seqretry(&rename_lock, seq))) { + spin_unlock(&new->d_lock); + new = NULL; +From 868baf07b1a259f5f3803c1dc2777b6c358f83cf Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Thu, 10 Feb 2011 21:26:13 -0500 +Subject: ftrace: Fix memory leak with function graph and cpu hotplug + +From: Steven Rostedt + +commit 868baf07b1a259f5f3803c1dc2777b6c358f83cf upstream. + +When the fuction graph tracer starts, it needs to make a special +stack for each task to save the real return values of the tasks. +All running tasks have this stack created, as well as any new +tasks. + +On CPU hot plug, the new idle task will allocate a stack as well +when init_idle() is called. The problem is that cpu hotplug does +not create a new idle_task. Instead it uses the idle task that +existed when the cpu went down. + +ftrace_graph_init_task() will add a new ret_stack to the task +that is given to it. Because a clone will make the task +have a stack of its parent it does not check if the task's +ret_stack is already NULL or not. When the CPU hotplug code +starts a CPU up again, it will allocate a new stack even +though one already existed for it. + +The solution is to treat the idle_task specially. In fact, the +function_graph code already does, just not at init_idle(). +Instead of using the ftrace_graph_init_task() for the idle task, +which that function expects the task to be a clone, have a +separate ftrace_graph_init_idle_task(). Also, we will create a +per_cpu ret_stack that is used by the idle task. When we call +ftrace_graph_init_idle_task() it will check if the idle task's +ret_stack is NULL, if it is, then it will assign it the per_cpu +ret_stack. + +Reported-by: Benjamin Herrenschmidt +Suggested-by: Peter Zijlstra +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ftrace.h | 2 + + kernel/sched.c | 2 - + kernel/trace/ftrace.c | 52 ++++++++++++++++++++++++++++++++++++++++++------- + 3 files changed, 48 insertions(+), 8 deletions(-) + +--- a/include/linux/ftrace.h ++++ b/include/linux/ftrace.h +@@ -428,6 +428,7 @@ extern void unregister_ftrace_graph(void + + extern void ftrace_graph_init_task(struct task_struct *t); + extern void ftrace_graph_exit_task(struct task_struct *t); ++extern void ftrace_graph_init_idle_task(struct task_struct *t, int cpu); + + static inline int task_curr_ret_stack(struct task_struct *t) + { +@@ -451,6 +452,7 @@ static inline void unpause_graph_tracing + + static inline void ftrace_graph_init_task(struct task_struct *t) { } + static inline void ftrace_graph_exit_task(struct task_struct *t) { } ++static inline void ftrace_graph_init_idle_task(struct task_struct *t, int cpu) { } + + static inline int register_ftrace_graph(trace_func_graph_ret_t retfunc, + trace_func_graph_ent_t entryfunc) +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -5572,7 +5572,7 @@ void __cpuinit init_idle(struct task_str + * The idle tasks have their own, simple scheduling class: + */ + idle->sched_class = &idle_sched_class; +- ftrace_graph_init_task(idle); ++ ftrace_graph_init_idle_task(idle, cpu); + } + + /* +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -3328,7 +3328,7 @@ static int start_graph_tracing(void) + /* The cpu_boot init_task->ret_stack will never be freed */ + for_each_online_cpu(cpu) { + if (!idle_task(cpu)->ret_stack) +- ftrace_graph_init_task(idle_task(cpu)); ++ ftrace_graph_init_idle_task(idle_task(cpu), cpu); + } + + do { +@@ -3418,6 +3418,49 @@ void unregister_ftrace_graph(void) + mutex_unlock(&ftrace_lock); + } + ++static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack); ++ ++static void ++graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack) ++{ ++ atomic_set(&t->tracing_graph_pause, 0); ++ atomic_set(&t->trace_overrun, 0); ++ t->ftrace_timestamp = 0; ++ /* make curr_ret_stack visable before we add the ret_stack */ ++ smp_wmb(); ++ t->ret_stack = ret_stack; ++} ++ ++/* ++ * Allocate a return stack for the idle task. May be the first ++ * time through, or it may be done by CPU hotplug online. ++ */ ++void ftrace_graph_init_idle_task(struct task_struct *t, int cpu) ++{ ++ t->curr_ret_stack = -1; ++ /* ++ * The idle task has no parent, it either has its own ++ * stack or no stack at all. ++ */ ++ if (t->ret_stack) ++ WARN_ON(t->ret_stack != per_cpu(idle_ret_stack, cpu)); ++ ++ if (ftrace_graph_active) { ++ struct ftrace_ret_stack *ret_stack; ++ ++ ret_stack = per_cpu(idle_ret_stack, cpu); ++ if (!ret_stack) { ++ ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH ++ * sizeof(struct ftrace_ret_stack), ++ GFP_KERNEL); ++ if (!ret_stack) ++ return; ++ per_cpu(idle_ret_stack, cpu) = ret_stack; ++ } ++ graph_init_task(t, ret_stack); ++ } ++} ++ + /* Allocate a return stack for newly created task */ + void ftrace_graph_init_task(struct task_struct *t) + { +@@ -3433,12 +3476,7 @@ void ftrace_graph_init_task(struct task_ + GFP_KERNEL); + if (!ret_stack) + return; +- atomic_set(&t->tracing_graph_pause, 0); +- atomic_set(&t->trace_overrun, 0); +- t->ftrace_timestamp = 0; +- /* make curr_ret_stack visable before we add the ret_stack */ +- smp_wmb(); +- t->ret_stack = ret_stack; ++ graph_init_task(t, ret_stack); + } + } + +From 77eed821accf5dd962b1f13bed0680e217e49112 Mon Sep 17 00:00:00 2001 +From: Kamal Mostafa +Date: Thu, 3 Feb 2011 17:38:04 -0800 +Subject: x86: Fix panic when handling "mem={invalid}" param + +From: Kamal Mostafa + +commit 77eed821accf5dd962b1f13bed0680e217e49112 upstream. + +Avoid removing all of memory and panicing when "mem={invalid}" +is specified, e.g. mem=blahblah, mem=0, or mem=nopentium (on +platforms other than x86_32). + +Signed-off-by: Kamal Mostafa +BugLink: http://bugs.launchpad.net/bugs/553464 +Cc: Yinghai Lu +Cc: Len Brown +Cc: Rafael J. Wysocki +LKML-Reference: <1296783486-23033-1-git-send-email-kamal@canonical.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/e820.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/kernel/e820.c ++++ b/arch/x86/kernel/e820.c +@@ -856,6 +856,9 @@ static int __init parse_memopt(char *p) + + userdef = 1; + mem_size = memparse(p, &p); ++ /* don't remove all of memory when handling "mem={invalid}" param */ ++ if (mem_size == 0) ++ return -EINVAL; + e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); + + return 0; +From 9a6d44b9adb777ca9549e88cd55bd8f2673c52a2 Mon Sep 17 00:00:00 2001 +From: Kamal Mostafa +Date: Thu, 3 Feb 2011 17:38:05 -0800 +Subject: x86: Emit "mem=nopentium ignored" warning when not supported + +From: Kamal Mostafa + +commit 9a6d44b9adb777ca9549e88cd55bd8f2673c52a2 upstream. + +Emit warning when "mem=nopentium" is specified on any arch other +than x86_32 (the only that arch supports it). + +Signed-off-by: Kamal Mostafa +BugLink: http://bugs.launchpad.net/bugs/553464 +Cc: Yinghai Lu +Cc: Len Brown +Cc: Rafael J. Wysocki +LKML-Reference: <1296783486-23033-2-git-send-email-kamal@canonical.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/e820.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/e820.c ++++ b/arch/x86/kernel/e820.c +@@ -847,12 +847,15 @@ static int __init parse_memopt(char *p) + if (!p) + return -EINVAL; + +-#ifdef CONFIG_X86_32 + if (!strcmp(p, "nopentium")) { ++#ifdef CONFIG_X86_32 + setup_clear_cpu_cap(X86_FEATURE_PSE); + return 0; +- } ++#else ++ printk(KERN_WARNING "mem=nopentium ignored! (only supported on x86_32)\n"); ++ return -EINVAL; + #endif ++ } + + userdef = 1; + mem_size = memparse(p, &p); +From 64a3903d0885879ba8706a8bcf71c5e3e7664db2 Mon Sep 17 00:00:00 2001 +From: Seth Heasley +Date: Fri, 11 Mar 2011 11:57:42 -0800 +Subject: ahci: AHCI mode SATA patch for Intel Patsburg SATA RAID controller + +From: Seth Heasley + +commit 64a3903d0885879ba8706a8bcf71c5e3e7664db2 upstream. + +This patch adds an updated SATA RAID DeviceID for the Intel Patsburg PCH. + +Signed-off-by: Seth Heasley +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ahci.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -260,6 +260,7 @@ static const struct pci_device_id ahci_p + { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ + { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */ + { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ ++ { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ + { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ + + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ +From 467b41c688c79d1b5e076fbdf082f9cd5d6a000c Mon Sep 17 00:00:00 2001 +From: Per Jessen +Date: Tue, 8 Feb 2011 13:54:32 +0100 +Subject: ahci: recognize Marvell 88se9125 PCIe SATA 6.0 Gb/s controller + +From: Per Jessen + +commit 467b41c688c79d1b5e076fbdf082f9cd5d6a000c upstream. + +Recognize Marvell 88SE9125 PCIe SATA 6.0 Gb/s controller. + +Signed-off-by: Per Jessen +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ahci.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -384,6 +384,8 @@ static const struct pci_device_id ahci_p + .class = PCI_CLASS_STORAGE_SATA_AHCI, + .class_mask = 0xffffff, + .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ ++ { PCI_DEVICE(0x1b4b, 0x9125), ++ .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ + + /* Promise */ + { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ +From eb0e85e36b971ec31610eda7e3ff5c11c1c44785 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Thu, 24 Feb 2011 19:30:37 +0100 +Subject: libata: fix hotplug for drivers which don't implement LPM + +From: Tejun Heo + +commit eb0e85e36b971ec31610eda7e3ff5c11c1c44785 upstream. + +ata_eh_analyze_serror() suppresses hotplug notifications if LPM is +being used because LPM generates spurious hotplug events. It compared +whether link->lpm_policy was different from ATA_LPM_MAX_POWER to +determine whether LPM is enabled; however, this is incorrect as for +drivers which don't implement LPM, lpm_policy is always +ATA_LPM_UNKNOWN. This disabled hotplug detection for all drivers +which don't implement LPM. + +Fix it by comparing whether lpm_policy is greater than +ATA_LPM_MAX_POWER. + +Signed-off-by: Tejun Heo +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-eh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -1618,7 +1618,7 @@ static void ata_eh_analyze_serror(struct + * host links. For disabled PMP links, only N bit is + * considered as X bit is left at 1 for link plugging. + */ +- if (link->lpm_policy != ATA_LPM_MAX_POWER) ++ if (link->lpm_policy > ATA_LPM_MAX_POWER) + hotplug_mask = 0; /* hotplug doesn't work w/ LPM */ + else if (!(link->flags & ATA_LFLAG_DISABLED) || ata_is_host_link(link)) + hotplug_mask = SERR_PHYRDY_CHG | SERR_DEV_XCHG; +From 25ae21a10112875763c18b385624df713a288a05 Mon Sep 17 00:00:00 2001 +From: Sean Hefty +Date: Wed, 23 Feb 2011 08:11:32 -0800 +Subject: RDMA/cma: Fix crash in request handlers + +From: Sean Hefty + +commit 25ae21a10112875763c18b385624df713a288a05 upstream. + +Doug Ledford and Red Hat reported a crash when running the rdma_cm on +a real-time OS. The crash has the following call trace: + + cm_process_work + cma_req_handler + cma_disable_callback + rdma_create_id + kzalloc + init_completion + cma_get_net_info + cma_save_net_info + cma_any_addr + cma_zero_addr + rdma_translate_ip + rdma_copy_addr + cma_acquire_dev + rdma_addr_get_sgid + ib_find_cached_gid + cma_attach_to_dev + ucma_event_handler + kzalloc + ib_copy_ah_attr_to_user + cma_comp + +[ preempted ] + + cma_write + copy_from_user + ucma_destroy_id + copy_from_user + _ucma_find_context + ucma_put_ctx + ucma_free_ctx + rdma_destroy_id + cma_exch + cma_cancel_operation + rdma_node_get_transport + + rt_mutex_slowunlock + bad_area_nosemaphore + oops_enter + +They were able to reproduce the crash multiple times with the +following details: + + Crash seems to always happen on the: + mutex_unlock(&conn_id->handler_mutex); + as conn_id looks to have been freed during this code path. + +An examination of the code shows that a race exists in the request +handlers. When a new connection request is received, the rdma_cm +allocates a new connection identifier. This identifier has a single +reference count on it. If a user calls rdma_destroy_id() from another +thread after receiving a callback, rdma_destroy_id will proceed to +destroy the id and free the associated memory. However, the request +handlers may still be in the process of running. When control returns +to the request handlers, they can attempt to access the newly created +identifiers. + +Fix this by holding a reference on the newly created rdma_cm_id until +the request handler is through accessing it. + +Signed-off-by: Sean Hefty +Acked-by: Doug Ledford +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/cma.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -1210,6 +1210,11 @@ static int cma_req_handler(struct ib_cm_ + cm_id->context = conn_id; + cm_id->cm_handler = cma_ib_handler; + ++ /* ++ * Protect against the user destroying conn_id from another thread ++ * until we're done accessing it. ++ */ ++ atomic_inc(&conn_id->refcount); + ret = conn_id->id.event_handler(&conn_id->id, &event); + if (!ret) { + /* +@@ -1222,8 +1227,10 @@ static int cma_req_handler(struct ib_cm_ + ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); + mutex_unlock(&lock); + mutex_unlock(&conn_id->handler_mutex); ++ cma_deref_id(conn_id); + goto out; + } ++ cma_deref_id(conn_id); + + /* Destroy the CM ID by returning a non-zero value. */ + conn_id->cm_id.ib = NULL; +@@ -1425,17 +1432,25 @@ static int iw_conn_req_handler(struct iw + event.param.conn.private_data_len = iw_event->private_data_len; + event.param.conn.initiator_depth = attr.max_qp_init_rd_atom; + event.param.conn.responder_resources = attr.max_qp_rd_atom; ++ ++ /* ++ * Protect against the user destroying conn_id from another thread ++ * until we're done accessing it. ++ */ ++ atomic_inc(&conn_id->refcount); + ret = conn_id->id.event_handler(&conn_id->id, &event); + if (ret) { + /* User wants to destroy the CM ID */ + conn_id->cm_id.iw = NULL; + cma_exch(conn_id, CMA_DESTROYING); + mutex_unlock(&conn_id->handler_mutex); ++ cma_deref_id(conn_id); + rdma_destroy_id(&conn_id->id); + goto out; + } + + mutex_unlock(&conn_id->handler_mutex); ++ cma_deref_id(conn_id); + + out: + if (dev) +From 34d211a2d5df4984a35b18d8ccacbe1d10abb067 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Wed, 16 Mar 2011 08:04:07 -0700 +Subject: Increase OSF partition limit from 8 to 18 + +From: Linus Torvalds + +commit 34d211a2d5df4984a35b18d8ccacbe1d10abb067 upstream. + +It turns out that while a maximum of 8 partitions may be what people +"should" have had, you can actually fit up to 18 entries(*) in a sector. + +And some people clearly were taking advantage of that, like Michael +Cree, who had ten partitions on one of his OSF disks. + +(*) The OSF partition data starts at byte offset 64 in the first sector, + and the array of 16-byte partition entries start at offset 148 in + the on-disk partition structure. + +Reported-by: Michael Cree +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/partitions/osf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/partitions/osf.c ++++ b/fs/partitions/osf.c +@@ -10,7 +10,7 @@ + #include "check.h" + #include "osf.h" + +-#define MAX_OSF_PARTITIONS 8 ++#define MAX_OSF_PARTITIONS 18 + + int osf_partition(struct parsed_partitions *state) + { +From 29963437a48475036353b95ab142bf199adb909e Mon Sep 17 00:00:00 2001 +From: Sean Hefty +Date: Wed, 23 Feb 2011 08:17:40 -0800 +Subject: IB/cm: Bump reference count on cm_id before invoking callback + +From: Sean Hefty + +commit 29963437a48475036353b95ab142bf199adb909e upstream. + +When processing a SIDR REQ, the ib_cm allocates a new cm_id. The +refcount of the cm_id is initialized to 1. However, cm_process_work +will decrement the refcount after invoking all callbacks. The result +is that the cm_id will end up with refcount set to 0 by the end of the +sidr req handler. + +If a user tries to destroy the cm_id, the destruction will proceed, +under the incorrect assumption that no other threads are referencing +the cm_id. This can lead to a crash when the cm callback thread tries +to access the cm_id. + +This problem was noticed as part of a larger investigation with kernel +crashes in the rdma_cm when running on a real time OS. + +Signed-off-by: Sean Hefty +Acked-by: Doug Ledford +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/cm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -2989,6 +2989,7 @@ static int cm_sidr_req_handler(struct cm + goto out; /* No match. */ + } + atomic_inc(&cur_cm_id_priv->refcount); ++ atomic_inc(&cm_id_priv->refcount); + spin_unlock_irq(&cm.lock); + + cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler; +From 1d3e09a304e6c4e004ca06356578b171e8735d3c Mon Sep 17 00:00:00 2001 +From: Andreas Herrmann +Date: Tue, 15 Mar 2011 15:31:37 +0100 +Subject: x86, quirk: Fix SB600 revision check + +From: Andreas Herrmann + +commit 1d3e09a304e6c4e004ca06356578b171e8735d3c upstream. + +Commit 7f74f8f28a2bd9db9404f7d364e2097a0c42cc12 +(x86 quirk: Fix polarity for IRQ0 pin2 override on SB800 +systems) introduced a regression. It removed some SB600 specific +code to determine the revision ID without adapting a +corresponding revision ID check for SB600. + +See this mail thread: + + http://marc.info/?l=linux-kernel&m=129980296006380&w=2 + +This patch adapts the corresponding check to cover all SB600 +revisions. + +Tested-by: Wang Lei +Signed-off-by: Andreas Herrmann +Cc: Andrew Morton +LKML-Reference: <20110315143137.GD29499@alberich.amd.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/early-quirks.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -159,7 +159,12 @@ static void __init ati_bugs_contd(int nu + if (rev >= 0x40) + acpi_fix_pin2_polarity = 1; + +- if (rev > 0x13) ++ /* ++ * SB600: revisions 0x11, 0x12, 0x13, 0x14, ... ++ * SB700: revisions 0x39, 0x3a, ... ++ * SB800: revisions 0x40, 0x41, ... ++ */ ++ if (rev >= 0x39) + return; + + if (acpi_use_timer_override) +From 6f3946b421395ff853bc0bcdab9c26b50ebbba8f Mon Sep 17 00:00:00 2001 +From: Steven J. Magnani +Date: Thu, 10 Feb 2011 12:12:13 -0600 +Subject: microblaze: Fix /dev/zero corruption from __clear_user() + +From: Steven J. Magnani + +commit 6f3946b421395ff853bc0bcdab9c26b50ebbba8f upstream. + +A userland read of more than PAGE_SIZE bytes from /dev/zero results in +(a) not all of the bytes returned being zero, and +(b) memory corruption due to zeroing of bytes beyond the user buffer. + +This is caused by improper constraints on the assembly __clear_user function. +The constrints don't indicate to the compiler that the pointer argument is +modified. Since the function is inline, this results in double-incrementing +of the pointer when __clear_user() is invoked through a multi-page read() of +/dev/zero. + +Signed-off-by: Steven J. Magnani +Acked-by: Michal Simek +Signed-off-by: Greg Kroah-Hartman + +--- + arch/microblaze/include/asm/uaccess.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/microblaze/include/asm/uaccess.h ++++ b/arch/microblaze/include/asm/uaccess.h +@@ -120,16 +120,16 @@ static inline unsigned long __must_check + { + /* normal memset with two words to __ex_table */ + __asm__ __volatile__ ( \ +- "1: sb r0, %2, r0;" \ ++ "1: sb r0, %1, r0;" \ + " addik %0, %0, -1;" \ + " bneid %0, 1b;" \ +- " addik %2, %2, 1;" \ ++ " addik %1, %1, 1;" \ + "2: " \ + __EX_TABLE_SECTION \ + ".word 1b,2b;" \ + ".previous;" \ +- : "=r"(n) \ +- : "0"(n), "r"(to) ++ : "=r"(n), "=r"(to) \ ++ : "0"(n), "1"(to) + ); + return n; + } +From 0e00f7aed6af21fc09b2a94d28bc34e449bd3a53 Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Thu, 3 Mar 2011 11:01:37 -0500 +Subject: x86: stop_machine_text_poke() should issue sync_core() + +From: Mathieu Desnoyers + +commit 0e00f7aed6af21fc09b2a94d28bc34e449bd3a53 upstream. + +Intel Archiecture Software Developer's Manual section 7.1.3 specifies that a +core serializing instruction such as "cpuid" should be executed on _each_ core +before the new instruction is made visible. + +Failure to do so can lead to unspecified behavior (Intel XMC erratas include +General Protection Fault in the list), so we should avoid this at all cost. + +This problem can affect modified code executed by interrupt handlers after +interrupt are re-enabled at the end of stop_machine, because no core serializing +instruction is executed between the code modification and the moment interrupts +are reenabled. + +Because stop_machine_text_poke performs the text modification from the first CPU +decrementing stop_machine_first, modified code executed in thread context is +also affected by this problem. To explain why, we have to split the CPUs in two +categories: the CPU that initiates the text modification (calls text_poke_smp) +and all the others. The scheduler, executed on all other CPUs after +stop_machine, issues an "iret" core serializing instruction, and therefore +handles core serialization for all these CPUs. However, the text modification +initiator can continue its execution on the same thread and access the modified +text without any scheduler call. Given that the CPU that initiates the code +modification is not guaranteed to be the one actually performing the code +modification, it falls into the XMC errata. + +Q: Isn't this executed from an IPI handler, which will return with IRET (a + serializing instruction) anyway? +A: No, now stop_machine uses per-cpu workqueue, so that handler will be + executed from worker threads. There is no iret anymore. + +Signed-off-by: Mathieu Desnoyers +LKML-Reference: <20110303160137.GB1590@Krystal> +Reviewed-by: Masami Hiramatsu +Cc: Arjan van de Ven +Cc: Peter Zijlstra +Cc: Steven Rostedt +Cc: Andrew Morton +Cc: Andi Kleen +Cc: Frederic Weisbecker +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/alternative.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/alternative.c ++++ b/arch/x86/kernel/alternative.c +@@ -620,7 +620,12 @@ static int __kprobes stop_machine_text_p + flush_icache_range((unsigned long)p->addr, + (unsigned long)p->addr + p->len); + } +- ++ /* ++ * Intel Archiecture Software Developer's Manual section 7.1.3 specifies ++ * that a core serializing instruction such as "cpuid" should be ++ * executed on _each_ core before the new instruction is made visible. ++ */ ++ sync_core(); + return 0; + } + +From eae61f3c829439f8f9121b5cd48a14be04df451f Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Wed, 2 Mar 2011 16:54:24 +0900 +Subject: TOMOYO: Fix memory leak upon file open. + +From: Tetsuo Handa + +commit eae61f3c829439f8f9121b5cd48a14be04df451f upstream. + +In tomoyo_check_open_permission() since 2.6.36, TOMOYO was by error +recalculating already calculated pathname when checking allow_rewrite +permission. As a result, memory will leak whenever a file is opened for writing +without O_APPEND flag. Also, performance will degrade because TOMOYO is +calculating pathname regardless of profile configuration. +This patch fixes the leak and performance degrade. + +Signed-off-by: Tetsuo Handa +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/tomoyo/file.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/security/tomoyo/file.c ++++ b/security/tomoyo/file.c +@@ -927,7 +927,7 @@ int tomoyo_check_open_permission(struct + struct path *path, const int flag) + { + const u8 acc_mode = ACC_MODE(flag); +- int error = -ENOMEM; ++ int error = 0; + struct tomoyo_path_info buf; + struct tomoyo_request_info r; + int idx; +@@ -938,9 +938,6 @@ int tomoyo_check_open_permission(struct + buf.name = NULL; + r.mode = TOMOYO_CONFIG_DISABLED; + idx = tomoyo_read_lock(); +- if (!tomoyo_get_realpath(&buf, path)) +- goto out; +- error = 0; + /* + * If the filename is specified by "deny_rewrite" keyword, + * we need to check "allow_rewrite" permission when the filename is not +From 8692d00e996ed2a6560702623e5cb646da0f9767 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sat, 5 Feb 2011 10:08:21 +0000 +Subject: drm/i915: Replace vblank PM QoS with "Interrupt-Based AGPBUSY#" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Chris Wilson + +commit 8692d00e996ed2a6560702623e5cb646da0f9767 upstream. + +I stumbled over this magic bit in the gen3 INSTPM: + +Bit11 Interrupt-Based AGPBUSY# Enable: + +‘0’ = Pending GMCH interrupts will not cause AGPBUSY# assertion. +‘1’ = Pending GMCH interrupts will cause AGPBUSY# assertion and hence + can cause the CPU to exit C3. There is no suppression of cacheable + writes. + +Note that in either case in C3 the interrupts are not lost. They will be +forwarded to the ICH when the GMCH is out of C3. + +Signed-off-by: Chris Wilson +Tested-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_irq.c | 9 +++++++++ + drivers/gpu/drm/i915/i915_reg.h | 5 ++++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1377,7 +1377,12 @@ int i915_enable_vblank(struct drm_device + else + i915_enable_pipestat(dev_priv, pipe, + PIPE_VBLANK_INTERRUPT_ENABLE); ++ ++ /* maintain vblank delivery even in deep C-states */ ++ if (dev_priv->info->gen == 3) ++ I915_WRITE(INSTPM, INSTPM_AGPBUSY_DIS << 16); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); ++ + return 0; + } + +@@ -1390,6 +1395,10 @@ void i915_disable_vblank(struct drm_devi + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); ++ if (dev_priv->info->gen == 3) ++ I915_WRITE(INSTPM, ++ INSTPM_AGPBUSY_DIS << 16 | INSTPM_AGPBUSY_DIS); ++ + if (HAS_PCH_SPLIT(dev)) + ironlake_disable_display_irq(dev_priv, (pipe == 0) ? + DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -405,9 +405,12 @@ + #define I915_ERROR_INSTRUCTION (1<<0) + #define INSTPM 0x020c0 + #define INSTPM_SELF_EN (1<<12) /* 915GM only */ ++#define INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts ++ will not assert AGPBUSY# and will only ++ be delivered when out of C3. */ + #define ACTHD 0x020c8 + #define FW_BLC 0x020d8 +-#define FW_BLC2 0x020dc ++#define FW_BLC2 0x020dc + #define FW_BLC_SELF 0x020e0 /* 915+ only */ + #define FW_BLC_SELF_EN_MASK (1<<31) + #define FW_BLC_SELF_FIFO_MASK (1<<16) /* 945 only */ +From 942b0e95c34f1ba432d08e1c0288ed032d32c3b2 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 14 Mar 2011 23:18:00 -0400 +Subject: drm/radeon/kms: fix typo in atom overscan setup + +From: Alex Deucher + +commit 942b0e95c34f1ba432d08e1c0288ed032d32c3b2 upstream. + +Typo in the aspect scale setup. + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -61,8 +61,8 @@ static void atombios_overscan_setup(stru + args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); + args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); + } else if (a2 > a1) { +- args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); +- args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); ++ args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); ++ args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); + } + break; + case RMX_FULL: +From 007c80a5497a3f9c8393960ec6e6efd30955dcb1 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Tue, 15 Mar 2011 11:40:00 +0000 +Subject: drm: Hold the mode mutex whilst probing for sysfs status + +From: Chris Wilson + +commit 007c80a5497a3f9c8393960ec6e6efd30955dcb1 upstream. + +As detect will use hw registers and may modify structures, it needs to be +serialised by use of the dev->mode_config.mutex. Make it so. + +Otherwise, we may cause random crashes as the sysfs file is queried +whilst a concurrent hotplug poll is being run. For example: + +[ 1189.189626] BUG: unable to handle kernel NULL pointer dereference at 00000100 +[ 1189.189821] IP: [] intel_tv_detect_type+0xa2/0x203 [i915] +[ 1189.190020] *pde = 00000000 +[ 1189.190104] Oops: 0000 [#1] SMP +[ 1189.190209] last sysfs file: /sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-SVIDEO-1/status +[ 1189.190412] Modules linked in: mperf cpufreq_conservative cpufreq_userspace cpufreq_powersave cpufreq_stats decnet uinput fuse loop joydev snd_hd a_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_pcm_oss snd_mixer_oss snd_pcm i915 snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq drm_kms_helper snd_timer uvcvideo d rm snd_seq_device eeepc_laptop tpm_tis usbhid videodev i2c_algo_bit v4l1_compat snd sparse_keymap i2c_core hid serio_raw tpm psmouse evdev tpm_bios rfkill shpchp ac processor rng_c ore battery video power_supply soundcore pci_hotplug button output snd_page_alloc usb_storage uas ext3 jbd mbcache sd_mod crc_t10dif ata_generic ahci libahci ata_piix libata uhci_h cd ehci_hcd scsi_mod usbcore thermal atl2 thermal_sys nls_base [last unloaded: scsi_wait_scan] +[ 1189.192007] +[ 1189.192007] Pid: 1464, comm: upowerd Not tainted 2.6.37-2-686 #1 ASUSTeK Computer INC. 701/701 +[ 1189.192007] EIP: 0060:[] EFLAGS: 00010246 CPU: 0 +[ 1189.192007] EIP is at intel_tv_detect_type+0xa2/0x203 [i915] +[ 1189.192007] EAX: 00000000 EBX: dca74000 ECX: e0f68004 EDX: 00068004 +[ 1189.192007] ESI: dd110c00 EDI: 400c0c37 EBP: dca7429c ESP: de365e2c +[ 1189.192007] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 +[ 1189.192007] Process upowerd (pid: 1464, ti=de364000 task=dcc8acb0 task.ti=de364000) +[ 1189.192007] Stack: Mar 15 03:43:23 hostname kernel: [ 1189.192007] e0c2cda4 70000000 400c0c30 00000000 dd111000 de365e54 de365f24 dd110c00 +[ 1189.192007] e0c22203 01000000 00000003 00000000 00000000 00000000 00000000 4353544e +[ 1189.192007] 30383420 00000069 00000000 00000000 00000000 00000000 00000000 00000000 +[ 1189.192007] Call Trace: Mar 15 03:43:23 hostname kernel: [ 1189.192007] [] ? intel_tv_detect+0x89/0x12d [i915] +[ 1189.192007] [] ? status_show+0x0/0x2f [drm] +[ 1189.192007] [] ? status_show+0x14/0x2f [drm] + +[Digression: what is upowerd doing reading those power hungry files?] + +Reported-by: Paul Menzel +Signed-off-by: Chris Wilson +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/drm_sysfs.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/gpu/drm/drm_sysfs.c ++++ b/drivers/gpu/drm/drm_sysfs.c +@@ -158,8 +158,15 @@ static ssize_t status_show(struct device + { + struct drm_connector *connector = to_drm_connector(device); + enum drm_connector_status status; ++ int ret; ++ ++ ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex); ++ if (ret) ++ return ret; + + status = connector->funcs->detect(connector, true); ++ mutex_unlock(&connector->dev->mode_config.mutex); ++ + return snprintf(buf, PAGE_SIZE, "%s\n", + drm_get_connector_status_name(status)); + } +From 0a8d7cb0c8182df7a28ad719780071178c386f0f Mon Sep 17 00:00:00 2001 +From: Senthil Balasubramanian +Date: Wed, 22 Dec 2010 19:17:18 +0530 +Subject: ath9k_hw: read and backup AR_WA register value even before chip reset on. + +From: Senthil Balasubramanian + +commit 0a8d7cb0c8182df7a28ad719780071178c386f0f upstream. + +We need to read and backup AR_WA register value permanently and reading +this after the chip is awakened results in this register being zeroed out. + +This seems to fix the ASPM with L1 enabled issue that we have observed. +The laptop becomes very slow and hangs mostly with ASPM L1 enabled without +this fix. + +Signed-off-by: Senthil Balasubramanian +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hw.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -495,6 +495,15 @@ static int __ath9k_hw_init(struct ath_hw + if (ah->hw_version.devid == AR5416_AR9100_DEVID) + ah->hw_version.macVersion = AR_SREV_VERSION_9100; + ++ /* ++ * Read back AR_WA into a permanent copy and set bits 14 and 17. ++ * We need to do this to avoid RMW of this register. We cannot ++ * read the reg when chip is asleep. ++ */ ++ ah->WARegVal = REG_READ(ah, AR_WA); ++ ah->WARegVal |= (AR_WA_D3_L1_DISABLE | ++ AR_WA_ASPM_TIMER_BASED_DISABLE); ++ + if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { + ath_err(common, "Couldn't reset chip\n"); + return -EIO; +@@ -563,14 +572,6 @@ static int __ath9k_hw_init(struct ath_hw + + ath9k_hw_init_mode_regs(ah); + +- /* +- * Read back AR_WA into a permanent copy and set bits 14 and 17. +- * We need to do this to avoid RMW of this register. We cannot +- * read the reg when chip is asleep. +- */ +- ah->WARegVal = REG_READ(ah, AR_WA); +- ah->WARegVal |= (AR_WA_D3_L1_DISABLE | +- AR_WA_ASPM_TIMER_BASED_DISABLE); + + if (ah->is_pciexpress) + ath9k_hw_configpcipowersave(ah, 0, 0); +From ac45c12dfb3f727a5a7a3332ed9c11b4a5ab287e Mon Sep 17 00:00:00 2001 +From: Senthil Balasubramanian +Date: Wed, 22 Dec 2010 21:14:20 +0530 +Subject: ath9k_hw: Fix incorrect macversion and macrev checks + +From: Senthil Balasubramanian + +commit ac45c12dfb3f727a5a7a3332ed9c11b4a5ab287e upstream. + +There are few places where we are checking for macversion and revsions +before RTC is powered ON. However we are reading the macversion and +revisions only after RTC is powered ON and so both macversion and +revisions are actully zero and this leads to incorrect srev checks + +Incorrect srev checks can cause registers to be configured wrongly and can +cause unexpected behavior. Fixing this seems to address the ASPM issue that +we have observed. The laptop becomes very slow and hangs mostly with ASPM L1 +enabled without this fix. + +fix this by reading the macversion and revisisons even before we start +using them. There is no reason why should we delay reading this info +until RTC is powered on as this is just a register information. + +Signed-off-by: Senthil Balasubramanian +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/hw.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -504,6 +504,8 @@ static int __ath9k_hw_init(struct ath_hw + ah->WARegVal |= (AR_WA_D3_L1_DISABLE | + AR_WA_ASPM_TIMER_BASED_DISABLE); + ++ ath9k_hw_read_revisions(ah); ++ + if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { + ath_err(common, "Couldn't reset chip\n"); + return -EIO; +@@ -1083,8 +1085,6 @@ static bool ath9k_hw_set_reset_power_on( + return false; + } + +- ath9k_hw_read_revisions(ah); +- + return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM); + } + +From 2e286947f1294239527c11f9f466ddce6466455b Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 9 Mar 2011 01:48:12 +0100 +Subject: ath9k: remove support for the FIF_PROMISC_IN_BSS filter flag + +From: Felix Fietkau + +commit 2e286947f1294239527c11f9f466ddce6466455b upstream. + +The hardware rx filter flag triggered by FIF_PROMISC_IN_BSS is overly broad +and covers even frames with PHY errors. When this flag is enabled, this message +shows up frequently during scanning or hardware resets: + +ath: Could not stop RX, we could be confusing the DMA engine when we start RX up + +Since promiscuous mode is usually not particularly useful, yet enabled by +default by bridging (either used normally in 4-addr mode, or with hacks +for various virtualization software), we should sacrifice it for better +reliability during normal operation. + +This patch leaves it enabled if there are active monitor mode interfaces, since +it's very useful for debugging. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/recv.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -439,9 +439,7 @@ u32 ath_calcrxfilter(struct ath_softc *s + * mode interface or when in monitor mode. AP mode does not need this + * since it receives all in-BSS frames anyway. + */ +- if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && +- (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || +- (sc->sc_ah->is_monitoring)) ++ if (sc->sc_ah->is_monitoring) + rfilt |= ATH9K_RX_FILTER_PROM; + + if (sc->rx.rxfilter & FIF_CONTROL) +From d8653d305ef66861c91fa7455fb8038460a7274c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 25 Jan 2011 14:15:11 +0000 +Subject: serial: mrst_max3110: make buffer larger + +From: Dan Carpenter + +commit d8653d305ef66861c91fa7455fb8038460a7274c upstream. + +This is used to store the spi_device ->modalias so they have to be the same +size. SPI_NAME_SIZE is 32. + +Signed-off-by: Dan Carpenter +Signed-off-by: Alan Cox +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/mrst_max3110.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/mrst_max3110.c ++++ b/drivers/tty/serial/mrst_max3110.c +@@ -51,7 +51,7 @@ + struct uart_max3110 { + struct uart_port port; + struct spi_device *spi; +- char name[24]; ++ char name[SPI_NAME_SIZE]; + + wait_queue_head_t wq; + struct task_struct *main_thread; +From 95926d2db6256e08d06b753752a0d903a0580acc Mon Sep 17 00:00:00 2001 +From: Yin Kangkai +Date: Wed, 9 Feb 2011 11:34:20 +0800 +Subject: serial: also set the uartclk value in resume after goes to highspeed + +From: Yin Kangkai + +commit 95926d2db6256e08d06b753752a0d903a0580acc upstream. + +For any reason if the NS16550A was not work in high speed mode (e.g. we hold +NS16550A from going to high speed mode in autoconfig_16550a()), now we are +resume from suspend, we should also set the uartclk to the correct +value. Otherwise it is still the old 1843200 and that will bring issues. + +CC: Greg Kroah-Hartman +CC: David Woodhouse +CC: linux-kernel@vger.kernel.org +Signed-off-by: Yin Kangkai +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -3036,6 +3036,7 @@ void serial8250_resume_port(int line) + serial_outp(up, 0x04, tmp); + + serial_outp(up, UART_LCR, 0); ++ up->port.uartclk = 921600*16; + } + uart_resume_port(&serial8250_reg, &up->port); + } +From 0d0389e5414c8950b1613e8bdc74289cde3d6d98 Mon Sep 17 00:00:00 2001 +From: Yin Kangkai +Date: Wed, 9 Feb 2011 11:35:18 +0800 +Subject: serial: change the divisor latch only when prescalar actually changed + +From: Yin Kangkai + +commit 0d0389e5414c8950b1613e8bdc74289cde3d6d98 upstream. + +In 8250.c original ns16550 autoconfig code, we change the divisor latch when +we goto to high speed mode, we're assuming the previous speed is legacy. This +some times is not true. + +For example in a system with both CONFIG_SERIAL_8250 and +CONFIG_SERIAL_8250_PNP set, in this case, the code (autoconfig) will be called +twice, one in serial8250_init/probe() and the other is from +serial_pnp_probe. When serial_pnp_probe calls the autoconfig for NS16550A, +it's already in high speed mode, change the divisor latch (quot << 3) in this +case will make the UART console garbled. + +CC: Greg Kroah-Hartman +CC: David Woodhouse +CC: linux-kernel@vger.kernel.org +Signed-off-by: Yin Kangkai +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -954,6 +954,23 @@ static int broken_efr(struct uart_8250_p + return 0; + } + ++static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) ++{ ++ unsigned char status; ++ ++ status = serial_in(up, 0x04); /* EXCR2 */ ++#define PRESL(x) ((x) & 0x30) ++ if (PRESL(status) == 0x10) { ++ /* already in high speed mode */ ++ return 0; ++ } else { ++ status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ ++ status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ ++ serial_outp(up, 0x04, status); ++ } ++ return 1; ++} ++ + /* + * We know that the chip has FIFOs. Does it have an EFR? The + * EFR is located in the same register position as the IIR and +@@ -1025,12 +1042,8 @@ static void autoconfig_16550a(struct uar + quot = serial_dl_read(up); + quot <<= 3; + +- status1 = serial_in(up, 0x04); /* EXCR2 */ +- status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ +- status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ +- serial_outp(up, 0x04, status1); +- +- serial_dl_write(up, quot); ++ if (ns16550a_goto_highspeed(up)) ++ serial_dl_write(up, quot); + + serial_outp(up, UART_LCR, 0); + +@@ -3025,15 +3038,10 @@ void serial8250_resume_port(int line) + struct uart_8250_port *up = &serial8250_ports[line]; + + if (up->capabilities & UART_NATSEMI) { +- unsigned char tmp; +- + /* Ensure it's still in high speed mode */ + serial_outp(up, UART_LCR, 0xE0); + +- tmp = serial_in(up, 0x04); /* EXCR2 */ +- tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ +- tmp |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ +- serial_outp(up, 0x04, tmp); ++ ns16550a_goto_highspeed(up); + + serial_outp(up, UART_LCR, 0); + up->port.uartclk = 921600*16; +From 969e3033ae7733a0af8f7742ca74cd16c0857e71 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 23 Feb 2011 15:28:18 -0500 +Subject: USB: serial drivers need to use larger bulk-in buffers + +From: Alan Stern + +commit 969e3033ae7733a0af8f7742ca74cd16c0857e71 upstream. + +When a driver doesn't know how much data a device is going to send, +the buffer size should be at least as big as the endpoint's maxpacket +value. The serial drivers don't follow this rule; many of them +request only 256-byte bulk-in buffers. As a result, they suffer +overflow errors if a high-speed device wants to send a lot of data, +because high-speed bulk endpoints are required to have a maxpacket +size of 512. + +This patch (as1450) fixes the problem by using the driver's +bulk_in_size value as a minimum, always allocating buffers no smaller +than the endpoint's maxpacket size. + +Signed-off-by: Alan Stern +Tested-by: Flynn Marquardt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/usb-serial.c | 5 ++--- + include/linux/usb/serial.h | 3 ++- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -911,9 +911,8 @@ int usb_serial_probe(struct usb_interfac + dev_err(&interface->dev, "No free urbs available\n"); + goto probe_error; + } +- buffer_size = serial->type->bulk_in_size; +- if (!buffer_size) +- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); ++ buffer_size = max_t(int, serial->type->bulk_in_size, ++ le16_to_cpu(endpoint->wMaxPacketSize)); + port->bulk_in_size = buffer_size; + port->bulk_in_endpointAddress = endpoint->bEndpointAddress; + port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); +--- a/include/linux/usb/serial.h ++++ b/include/linux/usb/serial.h +@@ -191,7 +191,8 @@ static inline void usb_set_serial_data(s + * @id_table: pointer to a list of usb_device_id structures that define all + * of the devices this structure can support. + * @num_ports: the number of different ports this device will have. +- * @bulk_in_size: bytes to allocate for bulk-in buffer (0 = end-point size) ++ * @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer ++ * (0 = end-point size) + * @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size) + * @calc_num_ports: pointer to a function to determine how many ports this + * device has dynamically. It will be called after the probe() +From 6960f40a954619857e7095a6179eef896f297077 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 28 Feb 2011 10:34:06 +0100 +Subject: USB: serial/kobil_sct, fix potential tty NULL dereference + +From: Jiri Slaby + +commit 6960f40a954619857e7095a6179eef896f297077 upstream. + +Make sure that we check the return value of tty_port_tty_get. +Sometimes it may return NULL and we later dereference that. + +The only place here is in kobil_read_int_callback, so fix it. + +Signed-off-by: Jiri Slaby +Cc: Alan Cox +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/kobil_sct.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/serial/kobil_sct.c ++++ b/drivers/usb/serial/kobil_sct.c +@@ -372,7 +372,7 @@ static void kobil_read_int_callback(stru + } + + tty = tty_port_tty_get(&port->port); +- if (urb->actual_length) { ++ if (tty && urb->actual_length) { + + /* BEGIN DEBUG */ + /* +From 7a89e4cb9cdaba92f5fbc509945cf4e3c48db4e2 Mon Sep 17 00:00:00 2001 +From: Herton Ronaldo Krzesinski +Date: Wed, 9 Mar 2011 09:19:48 +0000 +Subject: USB: serial: option: Apply OPTION_BLACKLIST_SENDSETUP also for ZTE MF626 + +From: Herton Ronaldo Krzesinski + +commit 7a89e4cb9cdaba92f5fbc509945cf4e3c48db4e2 upstream. + +On https://bugs.launchpad.net/ubuntu/+source/linux/+bug/636091, one of +the cases reported is a big timeout on option_send_setup, which causes +some side effects as tty_lock is held. Looks like some of ZTE MF626 +devices also don't like the RTS/DTR setting in option_send_setup, like +with 4G XS Stick W14. The reporter confirms which this it solves the +long freezes in his system. + +Signed-off-by: Herton Ronaldo Krzesinski +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -652,7 +652,8 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, ++ 0xff, 0xff), .driver_info = (kernel_ulong_t)&four_g_w14_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, +From d0781383038e983a63843a9a6a067ed781db89c1 Mon Sep 17 00:00:00 2001 +From: wangyanqing +Date: Fri, 11 Mar 2011 06:24:38 -0800 +Subject: USB: serial: ch341: add new id + +From: wangyanqing + +commit d0781383038e983a63843a9a6a067ed781db89c1 upstream. + +I picked up a new DAK-780EX(professional digitl reverb/mix system), +which use CH341T chipset to communication with computer on 3/2011 +and the CH341T's vendor code is 1a86 + +Looking up the CH341T's vendor and product id's I see: + +1a86 QinHeng Electronics + 5523 CH341 in serial mode, usb to serial port converter + +CH341T,CH341 are the products of the same company, maybe +have some common hardware, and I test the ch341.c works +well with CH341T + +Cc: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ch341.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -75,6 +75,7 @@ static int debug; + static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x4348, 0x5523) }, + { USB_DEVICE(0x1a86, 0x7523) }, ++ { USB_DEVICE(0x1a86, 0x5523) }, + { }, + }; + MODULE_DEVICE_TABLE(usb, id_table); +From cecf826df8648c843ea8db63b1f82c154a74db36 Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Thu, 24 Feb 2011 14:49:00 -0500 +Subject: staging: winbond: needs for msleep and friends + +From: Jeff Mahoney + +commit cecf826df8648c843ea8db63b1f82c154a74db36 upstream. + +linux/delay.h is pulled in somehow on x86 but not on ia64 or powerpc. + +This fixes a build failure on those arches since they use [mu]delay. + +Signed-off-by: Jeff Mahoney +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/winbond/core.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/staging/winbond/core.h ++++ b/drivers/staging/winbond/core.h +@@ -3,6 +3,7 @@ + + #include + #include ++#include + + #include "wbhal.h" + #include "mto.h" +From ab42abf33a3efdf754710a0a513c00c40854cd61 Mon Sep 17 00:00:00 2001 +From: Felipe Contreras +Date: Fri, 11 Mar 2011 18:29:06 -0600 +Subject: staging: tidspbridge: protect dmm_map properly + +From: Felipe Contreras + +commit ab42abf33a3efdf754710a0a513c00c40854cd61 upstream. + +We need to protect not only the dmm_map list, but the individual +map_obj's, otherwise, we might be building the scatter-gather list with +garbage. So, use the existing proc_lock for that. + +I observed race conditions which caused kernel panics while running +stress tests, also, Tuomas Kulve found it happening quite often in +Gumstix Over. This patch fixes those. + +Cc: Tuomas Kulve +Signed-off-by: Felipe Contreras +Signed-off-by: Omar Ramirez Luna +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/tidspbridge/rmgr/proc.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +--- a/drivers/staging/tidspbridge/rmgr/proc.c ++++ b/drivers/staging/tidspbridge/rmgr/proc.c +@@ -781,12 +781,14 @@ int proc_begin_dma(void *hprocessor, voi + (u32)pmpu_addr, + ul_size, dir); + ++ mutex_lock(&proc_lock); ++ + /* find requested memory are in cached mapping information */ + map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); + if (!map_obj) { + pr_err("%s: find_containing_mapping failed\n", __func__); + status = -EFAULT; +- goto err_out; ++ goto no_map; + } + + if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { +@@ -795,6 +797,8 @@ int proc_begin_dma(void *hprocessor, voi + status = -EFAULT; + } + ++no_map: ++ mutex_unlock(&proc_lock); + err_out: + + return status; +@@ -819,21 +823,24 @@ int proc_end_dma(void *hprocessor, void + (u32)pmpu_addr, + ul_size, dir); + ++ mutex_lock(&proc_lock); ++ + /* find requested memory are in cached mapping information */ + map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); + if (!map_obj) { + pr_err("%s: find_containing_mapping failed\n", __func__); + status = -EFAULT; +- goto err_out; ++ goto no_map; + } + + if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { + pr_err("%s: InValid address parameters %p %x\n", + __func__, pmpu_addr, ul_size); + status = -EFAULT; +- goto err_out; + } + ++no_map: ++ mutex_unlock(&proc_lock); + err_out: + return status; + } +@@ -1726,9 +1733,8 @@ int proc_un_map(void *hprocessor, void * + (p_proc_object->hbridge_context, va_align, size_align); + } + +- mutex_unlock(&proc_lock); + if (status) +- goto func_end; ++ goto unmap_failed; + + /* + * A successful unmap should be followed by removal of map_obj +@@ -1737,6 +1743,9 @@ int proc_un_map(void *hprocessor, void * + */ + remove_mapping_information(pr_ctxt, (u32) map_addr, size_align); + ++unmap_failed: ++ mutex_unlock(&proc_lock); ++ + func_end: + dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", + __func__, hprocessor, map_addr, status); +From 6410db593e8c1b2b79a2f18554310d6da9415584 Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 28 Feb 2011 23:36:09 -0600 +Subject: rtl8187: Change rate-control feedback + +From: Larry Finger + +commit 6410db593e8c1b2b79a2f18554310d6da9415584 upstream. + +The driver for the RTL8187L chips returns IEEE80211_TX_STAT_ACK for all +packets, even if the maximum number of retries was exhausted. In addition +it fails to setup max_rates in the ieee80211_hw struct, This behavior +may be responsible for the problems noted in Bug 14168. As the bug is very +old, testers have not been found, and I do not have the case where the +indicated signal is less than -70 dBm. + +Signed-off-by: Larry Finger +Acked-by: Hin-Tak Leung +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtl818x/rtl8187/dev.c | 25 ++++++++++++++++++++----- + drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | 2 ++ + 2 files changed, 22 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c +@@ -871,23 +871,35 @@ static void rtl8187_work(struct work_str + /* The RTL8187 returns the retry count through register 0xFFFA. In + * addition, it appears to be a cumulative retry count, not the + * value for the current TX packet. When multiple TX entries are +- * queued, the retry count will be valid for the last one in the queue. +- * The "error" should not matter for purposes of rate setting. */ ++ * waiting in the queue, the retry count will be the total for all. ++ * The "error" may matter for purposes of rate setting, but there is ++ * no other choice with this hardware. ++ */ + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + work.work); + struct ieee80211_tx_info *info; + struct ieee80211_hw *dev = priv->dev; + static u16 retry; + u16 tmp; ++ u16 avg_retry; ++ int length; + + mutex_lock(&priv->conf_mutex); + tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); ++ length = skb_queue_len(&priv->b_tx_status.queue); ++ if (unlikely(!length)) ++ length = 1; ++ if (unlikely(tmp < retry)) ++ tmp = retry; ++ avg_retry = (tmp - retry) / length; + while (skb_queue_len(&priv->b_tx_status.queue) > 0) { + struct sk_buff *old_skb; + + old_skb = skb_dequeue(&priv->b_tx_status.queue); + info = IEEE80211_SKB_CB(old_skb); +- info->status.rates[0].count = tmp - retry + 1; ++ info->status.rates[0].count = avg_retry + 1; ++ if (info->status.rates[0].count > RETRY_COUNT) ++ info->flags &= ~IEEE80211_TX_STAT_ACK; + ieee80211_tx_status_irqsafe(dev, old_skb); + } + retry = tmp; +@@ -933,8 +945,8 @@ static int rtl8187_start(struct ieee8021 + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + RTL818X_TX_CONF_HW_SEQNUM | + RTL818X_TX_CONF_DISREQQSIZE | +- (7 << 8 /* short retry limit */) | +- (7 << 0 /* long retry limit */) | ++ (RETRY_COUNT << 8 /* short retry limit */) | ++ (RETRY_COUNT << 0 /* long retry limit */) | + (7 << 21 /* MAX TX DMA */)); + rtl8187_init_urbs(dev); + rtl8187b_init_status_urb(dev); +@@ -1378,6 +1390,9 @@ static int __devinit rtl8187_probe(struc + dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_RX_INCLUDES_FCS; ++ /* Initialize rate-control variables */ ++ dev->max_rates = 1; ++ dev->max_rate_tries = RETRY_COUNT; + + eeprom.data = dev; + eeprom.register_read = rtl8187_eeprom_register_read; +--- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h ++++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +@@ -35,6 +35,8 @@ + #define RFKILL_MASK_8187_89_97 0x2 + #define RFKILL_MASK_8198 0x4 + ++#define RETRY_COUNT 7 ++ + struct rtl8187_rx_info { + struct urb *urb; + struct ieee80211_hw *dev; +From b14e840d04dba211fbdc930247e379085623eacd Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 8 Feb 2011 21:07:40 +0100 +Subject: USB: isp1760: Implement solution for erratum 2 + +From: Sebastian Andrzej Siewior + +commit b14e840d04dba211fbdc930247e379085623eacd upstream. + +The document says: +|2.1 Problem description +| When at least two USB devices are simultaneously running, it is observed that +| sometimes the INT corresponding to one of the USB devices stops occurring. This may +| be observed sometimes with USB-to-serial or USB-to-network devices. +| The problem is not noticed when only USB mass storage devices are running. +|2.2 Implication +| This issue is because of the clearing of the respective Done Map bit on reading the ATL +| PTD Done Map register when an INT is generated by another PTD completion, but is not +| found set on that read access. In this situation, the respective Done Map bit will remain +| reset and no further INT will be asserted so the data transfer corresponding to that USB +| device will stop. +|2.3 Workaround +| An SOF INT can be used instead of an ATL INT with polling on Done bits. A time-out can +| be implemented and if a certain Done bit is never set, verification of the PTD completion +| can be done by reading PTD contents (valid bit). +| This is a proven workaround implemented in software. + +Russell King run into this with an USB-to-serial converter. This patch +implements his suggestion to enable the high frequent SOF interrupt only +at the time we have ATL packages queued. It goes even one step further +and enables the SOF interrupt only if we have more than one ATL packet +queued at the same time. + +Tested-by: Russell King +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/isp1760-hcd.c | 22 ++++++++++++++++------ + drivers/usb/host/isp1760-hcd.h | 1 + + 2 files changed, 17 insertions(+), 6 deletions(-) + +--- a/drivers/usb/host/isp1760-hcd.c ++++ b/drivers/usb/host/isp1760-hcd.c +@@ -33,6 +33,7 @@ struct isp1760_hcd { + struct inter_packet_info atl_ints[32]; + struct inter_packet_info int_ints[32]; + struct memory_chunk memory_pool[BLOCKS]; ++ u32 atl_queued; + + /* periodic schedule support */ + #define DEFAULT_I_TDPS 1024 +@@ -850,6 +851,11 @@ static void enqueue_an_ATL_packet(struct + skip_map &= ~queue_entry; + isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); + ++ priv->atl_queued++; ++ if (priv->atl_queued == 2) ++ isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, ++ hcd->regs + HC_INTERRUPT_ENABLE); ++ + buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); + buffstatus |= ATL_BUFFER; + isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); +@@ -992,6 +998,7 @@ static void do_atl_int(struct usb_hcd *u + u32 dw3; + + status = 0; ++ priv->atl_queued--; + + queue_entry = __ffs(done_map); + done_map &= ~(1 << queue_entry); +@@ -1054,11 +1061,6 @@ static void do_atl_int(struct usb_hcd *u + * device is not able to send data fast enough. + * This happens mostly on slower hardware. + */ +- printk(KERN_NOTICE "Reloading ptd %p/%p... qh %p read: " +- "%d of %zu done: %08x cur: %08x\n", qtd, +- urb, qh, PTD_XFERRED_LENGTH(dw3), +- qtd->length, done_map, +- (1 << queue_entry)); + + /* RL counter = ERR counter */ + dw3 &= ~(0xf << 19); +@@ -1086,6 +1088,11 @@ static void do_atl_int(struct usb_hcd *u + priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + + atl_regs, sizeof(ptd)); + ++ priv->atl_queued++; ++ if (priv->atl_queued == 2) ++ isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, ++ usb_hcd->regs + HC_INTERRUPT_ENABLE); ++ + buffstatus = isp1760_readl(usb_hcd->regs + + HC_BUFFER_STATUS_REG); + buffstatus |= ATL_BUFFER; +@@ -1191,6 +1198,9 @@ static void do_atl_int(struct usb_hcd *u + skip_map = isp1760_readl(usb_hcd->regs + + HC_ATL_PTD_SKIPMAP_REG); + } ++ if (priv->atl_queued <= 1) ++ isp1760_writel(INTERRUPT_ENABLE_MASK, ++ usb_hcd->regs + HC_INTERRUPT_ENABLE); + } + + static void do_intl_int(struct usb_hcd *usb_hcd) +@@ -1770,7 +1780,7 @@ static irqreturn_t isp1760_irq(struct us + goto leave; + + isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); +- if (imask & HC_ATL_INT) ++ if (imask & (HC_ATL_INT | HC_SOT_INT)) + do_atl_int(usb_hcd); + + if (imask & HC_INTL_INT) +--- a/drivers/usb/host/isp1760-hcd.h ++++ b/drivers/usb/host/isp1760-hcd.h +@@ -69,6 +69,7 @@ void deinit_kmem_cache(void); + + #define HC_INTERRUPT_ENABLE 0x314 + #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) ++#define INTERRUPT_ENABLE_SOT_MASK (HC_INTL_INT | HC_SOT_INT | HC_EOT_INT) + + #define HC_ISO_INT (1 << 9) + #define HC_ATL_INT (1 << 8) +From 294d95f2cbc2aef5346258f216cd9df570e271a5 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Tue, 11 Jan 2011 12:26:48 -0500 +Subject: ehci: Check individual port status registers on resume + +From: Matthew Garrett + +commit 294d95f2cbc2aef5346258f216cd9df570e271a5 upstream. + +If a device plug/unplug is detected on an ATI SB700 USB controller in D3, +it appears to set the port status register but not the controller status +register. As a result we'll fail to detect the plug event. Check the port +status register on resume as well in order to catch this case. + +Signed-off-by: Matthew Garrett +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-hub.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/ehci-hub.c ++++ b/drivers/usb/host/ehci-hub.c +@@ -106,6 +106,27 @@ static void ehci_handover_companion_port + ehci->owned_ports = 0; + } + ++static int ehci_port_change(struct ehci_hcd *ehci) ++{ ++ int i = HCS_N_PORTS(ehci->hcs_params); ++ ++ /* First check if the controller indicates a change event */ ++ ++ if (ehci_readl(ehci, &ehci->regs->status) & STS_PCD) ++ return 1; ++ ++ /* ++ * Not all controllers appear to update this while going from D3 to D0, ++ * so check the individual port status registers as well ++ */ ++ ++ while (i--) ++ if (ehci_readl(ehci, &ehci->regs->port_status[i]) & PORT_CSC) ++ return 1; ++ ++ return 0; ++} ++ + static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, + bool suspending, bool do_wakeup) + { +@@ -173,7 +194,7 @@ static void ehci_adjust_port_wakeup_flag + } + + /* Does the root hub have a port wakeup pending? */ +- if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)) ++ if (!suspending && ehci_port_change(ehci)) + usb_hcd_resume_root_hub(ehci_to_hcd(ehci)); + + spin_unlock_irqrestore(&ehci->lock, flags); +From 9b37596a2e860404503a3f2a6513db60c296bfdc Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 7 Mar 2011 11:11:52 -0500 +Subject: USB: move usbcore away from hcd->state + +From: Alan Stern + +commit 9b37596a2e860404503a3f2a6513db60c296bfdc upstream. + +The hcd->state variable is a disaster. It's not clearly owned by +either usbcore or the host controller drivers, and they both change it +from time to time, potentially stepping on each other's toes. It's +not protected by any locks. And there's no mechanism to prevent it +from going through an invalid transition. + +This patch (as1451) takes a first step toward fixing these problems. +As it turns out, usbcore uses hcd->state for essentially only two +things: checking whether the controller's root hub is running and +checking whether the controller has died. Therefore the patch adds +two new atomic bitflags to the hcd structure, to store these pieces of +information. The new flags are used only by usbcore, and a private +spinlock prevents invalid combinations (a dead controller's root hub +cannot be running). + +The patch does not change the places where usbcore sets hcd->state, +since HCDs may depend on them. Furthermore, there is one place in +usb_hcd_irq() where usbcore still must use hcd->state: An HCD's +interrupt handler can implicitly indicate that the controller died by +setting hcd->state to HC_STATE_HALT. Nevertheless, the new code is a +big improvement over the current code. + +The patch makes one other change. The hcd_bus_suspend() and +hcd_bus_resume() routines now check first whether the host controller +has died; if it has then they return immediately without calling the +HCD's bus_suspend or bus_resume methods. + +This fixes the major problem reported in Bugzilla #29902: The system +fails to suspend after a host controller dies during system resume. + +Signed-off-by: Alan Stern +Tested-by: Alex Terekhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd-pci.c | 13 ++++------ + drivers/usb/core/hcd.c | 55 +++++++++++++++++++++++++++++++++------------ + include/linux/usb/hcd.h | 4 +++ + 3 files changed, 51 insertions(+), 21 deletions(-) + +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -363,8 +363,7 @@ static int check_root_hub_suspended(stru + struct pci_dev *pci_dev = to_pci_dev(dev); + struct usb_hcd *hcd = pci_get_drvdata(pci_dev); + +- if (!(hcd->state == HC_STATE_SUSPENDED || +- hcd->state == HC_STATE_HALT)) { ++ if (HCD_RH_RUNNING(hcd)) { + dev_warn(dev, "Root hub is not suspended\n"); + return -EBUSY; + } +@@ -386,7 +385,7 @@ static int suspend_common(struct device + if (retval) + return retval; + +- if (hcd->driver->pci_suspend) { ++ if (hcd->driver->pci_suspend && !HCD_DEAD(hcd)) { + /* Optimization: Don't suspend if a root-hub wakeup is + * pending and it would cause the HCD to wake up anyway. + */ +@@ -427,7 +426,7 @@ static int resume_common(struct device * + struct usb_hcd *hcd = pci_get_drvdata(pci_dev); + int retval; + +- if (hcd->state != HC_STATE_SUSPENDED) { ++ if (HCD_RH_RUNNING(hcd)) { + dev_dbg(dev, "can't resume, not suspended!\n"); + return 0; + } +@@ -442,7 +441,7 @@ static int resume_common(struct device * + + clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + +- if (hcd->driver->pci_resume) { ++ if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) { + if (event != PM_EVENT_AUTO_RESUME) + wait_for_companions(pci_dev, hcd); + +@@ -475,10 +474,10 @@ static int hcd_pci_suspend_noirq(struct + + pci_save_state(pci_dev); + +- /* If the root hub is HALTed rather than SUSPENDed, ++ /* If the root hub is dead rather than suspended, + * disallow remote wakeup. + */ +- if (hcd->state == HC_STATE_HALT) ++ if (HCD_DEAD(hcd)) + device_set_wakeup_enable(dev, 0); + dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev)); + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -983,7 +983,7 @@ static int register_root_hub(struct usb_ + spin_unlock_irq (&hcd_root_hub_lock); + + /* Did the HC die before the root hub was registered? */ +- if (hcd->state == HC_STATE_HALT) ++ if (HCD_DEAD(hcd) || hcd->state == HC_STATE_HALT) + usb_hc_died (hcd); /* This time clean up */ + } + +@@ -1089,13 +1089,10 @@ int usb_hcd_link_urb_to_ep(struct usb_hc + * Check the host controller's state and add the URB to the + * endpoint's queue. + */ +- switch (hcd->state) { +- case HC_STATE_RUNNING: +- case HC_STATE_RESUMING: ++ if (HCD_RH_RUNNING(hcd)) { + urb->unlinked = 0; + list_add_tail(&urb->urb_list, &urb->ep->urb_list); +- break; +- default: ++ } else { + rc = -ESHUTDOWN; + goto done; + } +@@ -1913,7 +1910,7 @@ int usb_hcd_get_frame_number (struct usb + { + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + +- if (!HC_IS_RUNNING (hcd->state)) ++ if (!HCD_RH_RUNNING(hcd)) + return -ESHUTDOWN; + return hcd->driver->get_frame_number (hcd); + } +@@ -1930,9 +1927,15 @@ int hcd_bus_suspend(struct usb_device *r + + dev_dbg(&rhdev->dev, "bus %s%s\n", + (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend"); ++ if (HCD_DEAD(hcd)) { ++ dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "suspend"); ++ return 0; ++ } ++ + if (!hcd->driver->bus_suspend) { + status = -ENOENT; + } else { ++ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + hcd->state = HC_STATE_QUIESCING; + status = hcd->driver->bus_suspend(hcd); + } +@@ -1940,7 +1943,12 @@ int hcd_bus_suspend(struct usb_device *r + usb_set_device_state(rhdev, USB_STATE_SUSPENDED); + hcd->state = HC_STATE_SUSPENDED; + } else { +- hcd->state = old_state; ++ spin_lock_irq(&hcd_root_hub_lock); ++ if (!HCD_DEAD(hcd)) { ++ set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); ++ hcd->state = old_state; ++ } ++ spin_unlock_irq(&hcd_root_hub_lock); + dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", + "suspend", status); + } +@@ -1955,9 +1963,13 @@ int hcd_bus_resume(struct usb_device *rh + + dev_dbg(&rhdev->dev, "usb %s%s\n", + (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); ++ if (HCD_DEAD(hcd)) { ++ dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume"); ++ return 0; ++ } + if (!hcd->driver->bus_resume) + return -ENOENT; +- if (hcd->state == HC_STATE_RUNNING) ++ if (HCD_RH_RUNNING(hcd)) + return 0; + + hcd->state = HC_STATE_RESUMING; +@@ -1966,10 +1978,15 @@ int hcd_bus_resume(struct usb_device *rh + if (status == 0) { + /* TRSMRCY = 10 msec */ + msleep(10); +- usb_set_device_state(rhdev, rhdev->actconfig +- ? USB_STATE_CONFIGURED +- : USB_STATE_ADDRESS); +- hcd->state = HC_STATE_RUNNING; ++ spin_lock_irq(&hcd_root_hub_lock); ++ if (!HCD_DEAD(hcd)) { ++ usb_set_device_state(rhdev, rhdev->actconfig ++ ? USB_STATE_CONFIGURED ++ : USB_STATE_ADDRESS); ++ set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); ++ hcd->state = HC_STATE_RUNNING; ++ } ++ spin_unlock_irq(&hcd_root_hub_lock); + } else { + hcd->state = old_state; + dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", +@@ -2080,7 +2097,7 @@ irqreturn_t usb_hcd_irq (int irq, void * + */ + local_irq_save(flags); + +- if (unlikely(hcd->state == HC_STATE_HALT || !HCD_HW_ACCESSIBLE(hcd))) { ++ if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) { + rc = IRQ_NONE; + } else if (hcd->driver->irq(hcd) == IRQ_NONE) { + rc = IRQ_NONE; +@@ -2114,6 +2131,8 @@ void usb_hc_died (struct usb_hcd *hcd) + dev_err (hcd->self.controller, "HC died; cleaning up\n"); + + spin_lock_irqsave (&hcd_root_hub_lock, flags); ++ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); ++ set_bit(HCD_FLAG_DEAD, &hcd->flags); + if (hcd->rh_registered) { + clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); + +@@ -2256,6 +2275,12 @@ int usb_add_hcd(struct usb_hcd *hcd, + */ + device_init_wakeup(&rhdev->dev, 1); + ++ /* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is ++ * registered. But since the controller can die at any time, ++ * let's initialize the flag before touching the hardware. ++ */ ++ set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); ++ + /* "reset" is misnamed; its role is now one-time init. the controller + * should already have been reset (and boot firmware kicked off etc). + */ +@@ -2323,6 +2348,7 @@ int usb_add_hcd(struct usb_hcd *hcd, + return retval; + + error_create_attr_group: ++ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + if (HC_IS_RUNNING(hcd->state)) + hcd->state = HC_STATE_QUIESCING; + spin_lock_irq(&hcd_root_hub_lock); +@@ -2375,6 +2401,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) + usb_get_dev(rhdev); + sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group); + ++ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + if (HC_IS_RUNNING (hcd->state)) + hcd->state = HC_STATE_QUIESCING; + +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -99,6 +99,8 @@ struct usb_hcd { + #define HCD_FLAG_POLL_RH 2 /* poll for rh status? */ + #define HCD_FLAG_POLL_PENDING 3 /* status has changed? */ + #define HCD_FLAG_WAKEUP_PENDING 4 /* root hub is resuming? */ ++#define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ ++#define HCD_FLAG_DEAD 6 /* controller has died? */ + + /* The flags can be tested using these macros; they are likely to + * be slightly faster than test_bit(). +@@ -108,6 +110,8 @@ struct usb_hcd { + #define HCD_POLL_RH(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_RH)) + #define HCD_POLL_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_PENDING)) + #define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING)) ++#define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING)) ++#define HCD_DEAD(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEAD)) + + /* Flags that get set only during HCD registration or removal. */ + unsigned rh_registered:1;/* is root hub registered? */ +From bf161e85fb153c0dd5a95faca73fd6a9d237c389 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Wed, 23 Feb 2011 15:46:42 -0800 +Subject: xhci: Update internal dequeue pointers after stalls. + +From: Sarah Sharp + +commit bf161e85fb153c0dd5a95faca73fd6a9d237c389 upstream. + +When an endpoint stalls, the xHCI driver must move the endpoint ring's +dequeue pointer past the stalled transfer. To do that, the driver issues +a Set TR Dequeue Pointer command, which will complete some time later. + +Takashi was having issues with USB 1.1 audio devices that stalled, and his +analysis of the code was that the old code would not update the xHCI +driver's ring dequeue pointer after the command completes. However, the +dequeue pointer is set in xhci_find_new_dequeue_state(), just before the +set command is issued to the hardware. + +Setting the dequeue pointer before the Set TR Dequeue Pointer command +completes is a dangerous thing to do, since the xHCI hardware can fail the +command. Instead, store the new dequeue pointer in the xhci_virt_ep +structure, and update the ring's dequeue pointer when the Set TR dequeue +pointer command completes. + +While we're at it, make sure we can't queue another Set TR Dequeue Command +while the first one is still being processed. This just won't work with +the internal xHCI state code. I'm still not sure if this is the right +thing to do, since we might have a case where a driver queues multiple +URBs to a control ring, one of the URBs Stalls, and then the driver tries +to cancel the second URB. There may be a race condition there where the +xHCI driver might try to issue multiple Set TR Dequeue Pointer commands, +but I would have to think very hard about how the Stop Endpoint and +cancellation code works. Keep the fix simple until when/if we run into +that case. + +This patch should be queued to kernels all the way back to 2.6.31. + +Signed-off-by: Sarah Sharp +Tested-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 29 ++++++++++++++++++++++++++--- + drivers/usb/host/xhci.h | 9 +++++++++ + 2 files changed, 35 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -506,9 +506,6 @@ void xhci_find_new_dequeue_state(struct + addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr); + xhci_dbg(xhci, "New dequeue pointer = 0x%llx (DMA)\n", + (unsigned long long) addr); +- xhci_dbg(xhci, "Setting dequeue pointer in internal ring state.\n"); +- ep_ring->dequeue = state->new_deq_ptr; +- ep_ring->deq_seg = state->new_deq_seg; + } + + static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, +@@ -951,9 +948,26 @@ static void handle_set_deq_completion(st + } else { + xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n", + ep_ctx->deq); ++ if (xhci_trb_virt_to_dma(dev->eps[ep_index].queued_deq_seg, ++ dev->eps[ep_index].queued_deq_ptr) == ++ (ep_ctx->deq & ~(EP_CTX_CYCLE_MASK))) { ++ /* Update the ring's dequeue segment and dequeue pointer ++ * to reflect the new position. ++ */ ++ ep_ring->deq_seg = dev->eps[ep_index].queued_deq_seg; ++ ep_ring->dequeue = dev->eps[ep_index].queued_deq_ptr; ++ } else { ++ xhci_warn(xhci, "Mismatch between completed Set TR Deq " ++ "Ptr command & xHCI internal state.\n"); ++ xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", ++ dev->eps[ep_index].queued_deq_seg, ++ dev->eps[ep_index].queued_deq_ptr); ++ } + } + + dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING; ++ dev->eps[ep_index].queued_deq_seg = NULL; ++ dev->eps[ep_index].queued_deq_ptr = NULL; + /* Restart any rings with pending URBs */ + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + } +@@ -3229,6 +3243,7 @@ static int queue_set_tr_deq(struct xhci_ + u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); + u32 trb_stream_id = STREAM_ID_FOR_TRB(stream_id); + u32 type = TRB_TYPE(TRB_SET_DEQ); ++ struct xhci_virt_ep *ep; + + addr = xhci_trb_virt_to_dma(deq_seg, deq_ptr); + if (addr == 0) { +@@ -3237,6 +3252,14 @@ static int queue_set_tr_deq(struct xhci_ + deq_seg, deq_ptr); + return 0; + } ++ ep = &xhci->devs[slot_id]->eps[ep_index]; ++ if ((ep->ep_state & SET_DEQ_PENDING)) { ++ xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n"); ++ xhci_warn(xhci, "A Set TR Deq Ptr command is pending.\n"); ++ return 0; ++ } ++ ep->queued_deq_seg = deq_seg; ++ ep->queued_deq_ptr = deq_ptr; + return queue_command(xhci, lower_32_bits(addr) | cycle_state, + upper_32_bits(addr), trb_stream_id, + trb_slot_id | trb_ep_index | type, false); +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -644,6 +644,9 @@ struct xhci_ep_ctx { + #define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) + #define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) + ++/* deq bitmasks */ ++#define EP_CTX_CYCLE_MASK (1 << 0) ++ + + /** + * struct xhci_input_control_context +@@ -746,6 +749,12 @@ struct xhci_virt_ep { + struct timer_list stop_cmd_timer; + int stop_cmds_pending; + struct xhci_hcd *xhci; ++ /* Dequeue pointer and dequeue segment for a submitted Set TR Dequeue ++ * command. We'll need to update the ring's dequeue segment and dequeue ++ * pointer after the command completes. ++ */ ++ struct xhci_segment *queued_deq_seg; ++ union xhci_trb *queued_deq_ptr; + /* + * Sometimes the xHC can not process isochronous endpoint ring quickly + * enough, and it will miss some isoc tds on the ring and generate +From 01a1fdb9a7afa5e3c14c9316d6f380732750b4e4 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Wed, 23 Feb 2011 18:12:29 -0800 +Subject: xhci: Fix cycle bit calculation during stall handling. + +From: Sarah Sharp + +commit 01a1fdb9a7afa5e3c14c9316d6f380732750b4e4 upstream. + +When an endpoint stalls, we need to update the xHCI host's internal +dequeue pointer to move it past the stalled transfer. This includes +updating the cycle bit (TRB ownership bit) if we have moved the dequeue +pointer past a link TRB with the toggle cycle bit set. + +When we're trying to find the new dequeue segment, find_trb_seg() is +supposed to keep track of whether we've passed any link TRBs with the +toggle cycle bit set. However, this while loop's body + + while (cur_seg->trbs > trb || + &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) { + +Will never get executed if the ring only contains one segment. +find_trb_seg() will return immediately, without updating the new cycle +bit. Since find_trb_seg() has no idea where in the segment the TD that +stalled was, make the caller, xhci_find_new_dequeue_state(), check for +this special case and update the cycle bit accordingly. + +This patch should be queued to kernels all the way back to 2.6.31. + +Signed-off-by: Sarah Sharp +Tested-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -500,6 +500,20 @@ void xhci_find_new_dequeue_state(struct + state->new_cycle_state = ~(state->new_cycle_state) & 0x1; + next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); + ++ /* ++ * If there is only one segment in a ring, find_trb_seg()'s while loop ++ * will not run, and it will return before it has a chance to see if it ++ * needs to toggle the cycle bit. It can't tell if the stalled transfer ++ * ended just before the link TRB on a one-segment ring, or if the TD ++ * wrapped around the top of the ring, because it doesn't have the TD in ++ * question. Look for the one-segment case where stalled TRB's address ++ * is greater than the new dequeue pointer address. ++ */ ++ if (ep_ring->first_seg == ep_ring->first_seg->next && ++ state->new_deq_ptr < dev->eps[ep_index].stopped_trb) ++ state->new_cycle_state ^= 0x1; ++ xhci_dbg(xhci, "Cycle state = 0x%x\n", state->new_cycle_state); ++ + /* Don't update the ring cycle state for the producer (us). */ + xhci_dbg(xhci, "New dequeue segment = %p (virtual)\n", + state->new_deq_seg); +From 500132a0f26ad7d9916102193cbc6c1b1becb373 Mon Sep 17 00:00:00 2001 +From: Paul Zimmerman +Date: Mon, 28 Feb 2011 18:11:27 -0800 +Subject: USB: Add support for SuperSpeed isoc endpoints + +From: Paul Zimmerman + +commit 500132a0f26ad7d9916102193cbc6c1b1becb373 upstream. + +Use the Mult and bMaxBurst values from the endpoint companion +descriptor to calculate the max length of an isoc transfer. + +Add USB_SS_MULT macro to access Mult field of bmAttributes, at +Sarah's suggestion. + +This patch should be queued for the 2.6.36 and 2.6.37 stable trees, since +those were the first kernels to have isochronous support for SuperSpeed +devices. + +Signed-off-by: Paul Zimmerman +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/urb.c | 11 ++++++++++- + include/linux/usb/ch9.h | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/urb.c ++++ b/drivers/usb/core/urb.c +@@ -366,7 +366,16 @@ int usb_submit_urb(struct urb *urb, gfp_ + if (xfertype == USB_ENDPOINT_XFER_ISOC) { + int n, len; + +- /* FIXME SuperSpeed isoc endpoints have up to 16 bursts */ ++ /* SuperSpeed isoc endpoints have up to 16 bursts of up to ++ * 3 packets each ++ */ ++ if (dev->speed == USB_SPEED_SUPER) { ++ int burst = 1 + ep->ss_ep_comp.bMaxBurst; ++ int mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes); ++ max *= burst; ++ max *= mult; ++ } ++ + /* "high bandwidth" mode, 1-3 packets/uframe? */ + if (dev->speed == USB_SPEED_HIGH) { + int mult = 1 + ((max >> 11) & 0x03); +--- a/include/linux/usb/ch9.h ++++ b/include/linux/usb/ch9.h +@@ -585,6 +585,8 @@ struct usb_ss_ep_comp_descriptor { + #define USB_DT_SS_EP_COMP_SIZE 6 + /* Bits 4:0 of bmAttributes if this is a bulk endpoint */ + #define USB_SS_MAX_STREAMS(p) (1 << (p & 0x1f)) ++/* Bits 1:0 of bmAttributes if this is an isoc endpoint */ ++#define USB_SS_MULT(p) (1 + ((p) & 0x3)) + + /*-------------------------------------------------------------------------*/ + +From 32eea3884debb65ec1da633bc5df5aee23879865 Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Fri, 4 Mar 2011 13:37:50 +0100 +Subject: ALSA: HDA: Enable surround and subwoofer on Lenovo Ideapad Y530 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Henningsson + +commit 32eea3884debb65ec1da633bc5df5aee23879865 upstream. + +The pin config values would change the association instead of the +sequence, this commit fixes that up. + +Tested-by: Bartłomiej Żogała +Signed-off-by: David Henningsson +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10748,6 +10748,7 @@ static struct alc_config_preset alc882_p + */ + enum { + PINFIX_ABIT_AW9D_MAX, ++ PINFIX_LENOVO_Y530, + PINFIX_PB_M5210, + PINFIX_ACER_ASPIRE_7736, + }; +@@ -10762,6 +10763,14 @@ static const struct alc_fixup alc882_fix + { } + } + }, ++ [PINFIX_LENOVO_Y530] = { ++ .type = ALC_FIXUP_PINS, ++ .v.pins = (const struct alc_pincfg[]) { ++ { 0x15, 0x99130112 }, /* rear int speakers */ ++ { 0x16, 0x99130111 }, /* subwoofer */ ++ { } ++ } ++ }, + [PINFIX_PB_M5210] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { +@@ -10777,6 +10786,7 @@ static const struct alc_fixup alc882_fix + + static struct snd_pci_quirk alc882_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), ++ SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), + SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), + SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), + {} +From ebbeb3d6aa22433c218da6f29fd7b3ebc89b87ea Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Fri, 4 Mar 2011 14:08:30 +0100 +Subject: ALSA: HDA: Fix volume control naming for surround speakers on Realtek auto-parser +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Henningsson + +commit ebbeb3d6aa22433c218da6f29fd7b3ebc89b87ea upstream. + +When more than one pair of internal speakers is present, allow names +according to their channels. + +Tested-by: Bartłomiej Żogała +Signed-off-by: David Henningsson +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5151,7 +5151,9 @@ static const char *alc_get_line_out_pfx( + + switch (cfg->line_out_type) { + case AUTO_PIN_SPEAKER_OUT: +- return "Speaker"; ++ if (cfg->line_outs == 1) ++ return "Speaker"; ++ break; + case AUTO_PIN_HP_OUT: + return "Headphone"; + default: +From 7e59e097c09b82760bb0fe08b0fa2b704d76c3f4 Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Fri, 4 Mar 2011 14:22:25 +0100 +Subject: ALSA: HDA: Fixup unnecessary volume control index on Realtek ALC88x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Henningsson + +commit 7e59e097c09b82760bb0fe08b0fa2b704d76c3f4 upstream. + +Without this change, a volume control named "Surround" or "Side" would +get an unnecessary index, causing it to be ignored by the vmaster and +PulseAudio. + +Tested-by: Bartłomiej Żogała +Signed-off-by: David Henningsson +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5207,16 +5207,19 @@ static int alc880_auto_create_multi_out_ + return err; + } else { + const char *name = pfx; +- if (!name) ++ int index = i; ++ if (!name) { + name = chname[i]; ++ index = 0; ++ } + err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, +- name, i, ++ name, index, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, +- name, i, ++ name, index, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, + HDA_INPUT)); + if (err < 0) +From 0a3fabe30e1a3b2037a12b863b8c45fffce38ee9 Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Fri, 4 Mar 2011 16:54:52 +0100 +Subject: ALSA: HDA: Realtek ALC88x: Do not over-initialize speakers and hp that are primary outputs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Henningsson + +commit 0a3fabe30e1a3b2037a12b863b8c45fffce38ee9 upstream. + +Do not initialize again the what has already been initialized as +multi outs, as this breaks surround speakers. + +Tested-by: Bartłomiej Żogała +Signed-off-by: David Henningsson +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 37 +++++++++++++++++++++---------------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10844,23 +10844,28 @@ static void alc882_auto_init_hp_out(stru + hda_nid_t pin, dac; + int i; + +- for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { +- pin = spec->autocfg.hp_pins[i]; +- if (!pin) +- break; +- dac = spec->multiout.hp_nid; +- if (!dac) +- dac = spec->multiout.dac_nids[0]; /* to front */ +- alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); ++ if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) { ++ for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { ++ pin = spec->autocfg.hp_pins[i]; ++ if (!pin) ++ break; ++ dac = spec->multiout.hp_nid; ++ if (!dac) ++ dac = spec->multiout.dac_nids[0]; /* to front */ ++ alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); ++ } + } +- for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { +- pin = spec->autocfg.speaker_pins[i]; +- if (!pin) +- break; +- dac = spec->multiout.extra_out_nid[0]; +- if (!dac) +- dac = spec->multiout.dac_nids[0]; /* to front */ +- alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); ++ ++ if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) { ++ for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { ++ pin = spec->autocfg.speaker_pins[i]; ++ if (!pin) ++ break; ++ dac = spec->multiout.extra_out_nid[0]; ++ if (!dac) ++ dac = spec->multiout.dac_nids[0]; /* to front */ ++ alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); ++ } + } + } + +From 094a42452abd5564429045e210281c6d22e67fca Mon Sep 17 00:00:00 2001 +From: Vitaliy Kulikov +Date: Wed, 9 Mar 2011 19:47:43 -0600 +Subject: ALSA: hda - fix digital mic selection in mixer on 92HD8X codecs + +From: Vitaliy Kulikov + +commit 094a42452abd5564429045e210281c6d22e67fca upstream. + +When the mux for digital mic is different from the mux for other mics, +the current auto-parser doesn't handle them in a right way but provides +only one mic. This patch fixes the issue. + +Signed-off-by: Vitaliy Kulikov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_sigmatel.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -757,7 +757,7 @@ static int stac92xx_mux_enum_put(struct + struct sigmatel_spec *spec = codec->spec; + unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + const struct hda_input_mux *imux = spec->input_mux; +- unsigned int idx, prev_idx; ++ unsigned int idx, prev_idx, didx; + + idx = ucontrol->value.enumerated.item[0]; + if (idx >= imux->num_items) +@@ -769,7 +769,8 @@ static int stac92xx_mux_enum_put(struct + snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, + AC_VERB_SET_CONNECT_SEL, + imux->items[idx].index); +- if (prev_idx >= spec->num_analog_muxes) { ++ if (prev_idx >= spec->num_analog_muxes && ++ spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) { + imux = spec->dinput_mux; + /* 0 = analog */ + snd_hda_codec_write_cache(codec, +@@ -779,9 +780,13 @@ static int stac92xx_mux_enum_put(struct + } + } else { + imux = spec->dinput_mux; ++ /* first dimux item is hardcoded to select analog imux, ++ * so lets skip it ++ */ ++ didx = idx - spec->num_analog_muxes + 1; + snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, + AC_VERB_SET_CONNECT_SEL, +- imux->items[idx - 1].index); ++ imux->items[didx].index); + } + spec->cur_mux[adc_idx] = idx; + return 1; +From 584c0c4c359bdac37d94157f8d7fc513d26c8328 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 10 Mar 2011 12:51:11 +0100 +Subject: ALSA: hda - Initialize special cases for input src in init phase + +From: Takashi Iwai + +commit 584c0c4c359bdac37d94157f8d7fc513d26c8328 upstream. + +Currently some special handling for the unusual case like dual-ADCs +or a single-input-src is done in the tree-parse time in +set_capture_mixer(). But this setup could be overwritten by static +init verbs. + +This patch moves the initialization into the init phase so that +such input-src setup won't be lost. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -394,6 +394,7 @@ struct alc_spec { + /* other flags */ + unsigned int no_analog :1; /* digital I/O only */ + unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ ++ unsigned int single_input_src:1; + int init_amp; + int codec_variant; /* flag for other variants */ + +@@ -3919,6 +3920,8 @@ static struct hda_amp_list alc880_lg_loo + * Common callbacks + */ + ++static void alc_init_special_input_src(struct hda_codec *codec); ++ + static int alc_init(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; +@@ -3929,6 +3932,7 @@ static int alc_init(struct hda_codec *co + + for (i = 0; i < spec->num_init_verbs; i++) + snd_hda_sequence_write(codec, spec->init_verbs[i]); ++ alc_init_special_input_src(codec); + + if (spec->init_hook) + spec->init_hook(codec); +@@ -5590,6 +5594,7 @@ static void fixup_single_adc(struct hda_ + spec->capsrc_nids += i; + spec->adc_nids += i; + spec->num_adc_nids = 1; ++ spec->single_input_src = 1; + } + } + +@@ -5601,6 +5606,16 @@ static void fixup_dual_adc_switch(struct + init_capsrc_for_pin(codec, spec->int_mic.pin); + } + ++/* initialize some special cases for input sources */ ++static void alc_init_special_input_src(struct hda_codec *codec) ++{ ++ struct alc_spec *spec = codec->spec; ++ if (spec->dual_adc_switch) ++ fixup_dual_adc_switch(codec); ++ else if (spec->single_input_src) ++ init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); ++} ++ + static void set_capture_mixer(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; +@@ -5616,7 +5631,7 @@ static void set_capture_mixer(struct hda + int mux = 0; + int num_adcs = spec->num_adc_nids; + if (spec->dual_adc_switch) +- fixup_dual_adc_switch(codec); ++ num_adcs = 1; + else if (spec->auto_mic) + fixup_automic_adc(codec); + else if (spec->input_mux) { +@@ -5625,8 +5640,6 @@ static void set_capture_mixer(struct hda + else if (spec->input_mux->num_items == 1) + fixup_single_adc(codec); + } +- if (spec->dual_adc_switch) +- num_adcs = 1; + spec->cap_mixer = caps[mux][num_adcs - 1]; + } + } +From 2d9ca4e9f393d81d8f37ed37505aecbf3a5e1bd6 Mon Sep 17 00:00:00 2001 +From: Henrik Rydberg +Date: Wed, 9 Mar 2011 18:38:57 +0100 +Subject: HID: hid-magicmouse: Correct touch orientation direction + +From: Henrik Rydberg + +commit 2d9ca4e9f393d81d8f37ed37505aecbf3a5e1bd6 upstream. + +The magic trackpad and mouse both report touch orientation in opposite +direction to the bcm5974 driver and what is written in +Documents/input/multi-touch-protocol.txt. This patch reverts the +direction, so that all in-kernel devices with this feature behave the +same way. + +Since no known application has been utilizing this information yet, it +seems appropriate also for stable. + +Cc: Michael Poole +Signed-off-by: Henrik Rydberg +Acked-by: Chase Douglas +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-magicmouse.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -258,7 +258,7 @@ static void magicmouse_emit_touch(struct + input_report_abs(input, ABS_MT_TRACKING_ID, id); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); + input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); +- input_report_abs(input, ABS_MT_ORIENTATION, orientation); ++ input_report_abs(input, ABS_MT_ORIENTATION, -orientation); + input_report_abs(input, ABS_MT_POSITION_X, x); + input_report_abs(input, ABS_MT_POSITION_Y, y); + +@@ -397,7 +397,7 @@ static void magicmouse_setup_input(struc + input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); +- input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); ++ input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0); + + /* Note: Touch Y position from the device is inverted relative + * to how pointer motion is reported (and relative to how USB +From 270fdc0748bd3f7b625caff985f2fcf8e2185ec7 Mon Sep 17 00:00:00 2001 +From: Herton Ronaldo Krzesinski +Date: Wed, 16 Mar 2011 14:13:53 -0300 +Subject: HID: add support for Ortek PKB-1700 + +From: Herton Ronaldo Krzesinski + +commit 270fdc0748bd3f7b625caff985f2fcf8e2185ec7 upstream. + +As reported on http://ubuntuforums.org/showthread.php?t=1594007 the +PKB-1700 needs same special handling as WKB-2000. This change is +originally based on patch posted by user asmoore82 on the Ubuntu +forums. + +Signed-off-by: Herton Ronaldo Krzesinski +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/Kconfig | 4 ++-- + drivers/hid/hid-core.c | 1 + + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-ortek.c | 3 ++- + 4 files changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -319,10 +319,10 @@ config HID_NTRIG + Support for N-Trig touch screen. + + config HID_ORTEK +- tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad" ++ tristate "Ortek PKB-1700/WKB-2000 wireless keyboard and mouse trackpad" + depends on USB_HID + ---help--- +- Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. ++ Support for Ortek PKB-1700/WKB-2000 wireless keyboard + mouse trackpad. + + config HID_PANTHERLORD + tristate "Pantherlord/GreenAsia game controller" +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1400,6 +1400,7 @@ static const struct hid_device_id hid_ha + { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) }, + { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) }, + { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -466,6 +466,7 @@ + #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 + + #define USB_VENDOR_ID_ORTEK 0x05a4 ++#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 + #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 + + #define USB_VENDOR_ID_PANJIT 0x134c +--- a/drivers/hid/hid-ortek.c ++++ b/drivers/hid/hid-ortek.c +@@ -1,5 +1,5 @@ + /* +- * HID driver for Ortek WKB-2000 (wireless keyboard + mouse trackpad). ++ * HID driver for Ortek PKB-1700/WKB-2000 (wireless keyboard + mouse trackpad). + * Fixes LogicalMaximum error in USB report description, see + * http://bugzilla.kernel.org/show_bug.cgi?id=14787 + * +@@ -30,6 +30,7 @@ static __u8 *ortek_report_fixup(struct h + } + + static const struct hid_device_id ortek_devices[] = { ++ { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, + { } + }; +From b99af4b002e4908d1a5cdaf424529bdf1dc69768 Mon Sep 17 00:00:00 2001 +From: Brandeburg, Jesse +Date: Mon, 14 Feb 2011 09:05:02 -0800 +Subject: PCI: remove quirk for pre-production systems + +From: Brandeburg, Jesse + +commit b99af4b002e4908d1a5cdaf424529bdf1dc69768 upstream. + +Revert commit 7eb93b175d4de9438a4b0af3a94a112cb5266944 +Author: Yu Zhao +Date: Fri Apr 3 15:18:11 2009 +0800 + + PCI: SR-IOV quirk for Intel 82576 NIC + + If BIOS doesn't allocate resources for the SR-IOV BARs, zero the Flash + BAR and program the SR-IOV BARs to use the old Flash Memory Space. + + Please refer to Intel 82576 Gigabit Ethernet Controller Datasheet + section 7.9.2.14.2 for details. + http://download.intel.com/design/network/datashts/82576_Datasheet.pdf + + Signed-off-by: Yu Zhao + Signed-off-by: Jesse Barnes + +This quirk was added before SR-IOV was in production and now all machines that +originally had this issue alreayd have bios updates to correct the issue. The +quirk itself is no longer needed and in fact causes bugs if run. Remove it. + +Signed-off-by: Jesse Brandeburg +CC: Yu Zhao +CC: Jesse Barnes +Signed-off-by: Jesse Barnes +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/quirks.c | 52 --------------------------------------------------- + 1 file changed, 52 deletions(-) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -2618,58 +2618,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AT + + #endif /* CONFIG_PCI_MSI */ + +-#ifdef CONFIG_PCI_IOV +- +-/* +- * For Intel 82576 SR-IOV NIC, if BIOS doesn't allocate resources for the +- * SR-IOV BARs, zero the Flash BAR and program the SR-IOV BARs to use the +- * old Flash Memory Space. +- */ +-static void __devinit quirk_i82576_sriov(struct pci_dev *dev) +-{ +- int pos, flags; +- u32 bar, start, size; +- +- if (PAGE_SIZE > 0x10000) +- return; +- +- flags = pci_resource_flags(dev, 0); +- if ((flags & PCI_BASE_ADDRESS_SPACE) != +- PCI_BASE_ADDRESS_SPACE_MEMORY || +- (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != +- PCI_BASE_ADDRESS_MEM_TYPE_32) +- return; +- +- pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); +- if (!pos) +- return; +- +- pci_read_config_dword(dev, pos + PCI_SRIOV_BAR, &bar); +- if (bar & PCI_BASE_ADDRESS_MEM_MASK) +- return; +- +- start = pci_resource_start(dev, 1); +- size = pci_resource_len(dev, 1); +- if (!start || size != 0x400000 || start & (size - 1)) +- return; +- +- pci_resource_flags(dev, 1) = 0; +- pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); +- pci_write_config_dword(dev, pos + PCI_SRIOV_BAR, start); +- pci_write_config_dword(dev, pos + PCI_SRIOV_BAR + 12, start + size / 2); +- +- dev_info(&dev->dev, "use Flash Memory Space for SR-IOV BARs\n"); +-} +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov); +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); +- +-#endif /* CONFIG_PCI_IOV */ +- + /* Allow manual resource allocation for PCI hotplug bridges + * via pci=hpmemsize=nnM and pci=hpiosize=nnM parameters. For + * some PCI-PCI hotplug bridges, like PLX 6254 (former HINT HB6), +From cdb9755849fbaf2bb9c0a009ba5baa817a0f152d Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 28 Feb 2011 10:45:09 +0100 +Subject: PCI: add more checking to ICH region quirks + +From: Jiri Slaby + +commit cdb9755849fbaf2bb9c0a009ba5baa817a0f152d upstream. + +Per ICH4 and ICH6 specs, ACPI and GPIO regions are valid iff ACPI_EN +and GPIO_EN bits are set to 1. Add checks for these bits into the +quirks prior to the region creation. + +While at it, name the constants by macros. + +Signed-off-by: Jiri Slaby +Cc: Bjorn Helgaas +Cc: "David S. Miller" +Cc: Thomas Renninger +Signed-off-by: Jesse Barnes +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/quirks.c | 49 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 39 insertions(+), 10 deletions(-) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -533,6 +533,17 @@ static void __devinit quirk_piix4_acpi(s + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, quirk_piix4_acpi); + ++#define ICH_PMBASE 0x40 ++#define ICH_ACPI_CNTL 0x44 ++#define ICH4_ACPI_EN 0x10 ++#define ICH6_ACPI_EN 0x80 ++#define ICH4_GPIOBASE 0x58 ++#define ICH4_GPIO_CNTL 0x5c ++#define ICH4_GPIO_EN 0x10 ++#define ICH6_GPIOBASE 0x48 ++#define ICH6_GPIO_CNTL 0x4c ++#define ICH6_GPIO_EN 0x10 ++ + /* + * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at + * 0x40 (128 bytes of ACPI, GPIO & TCO registers) +@@ -541,12 +552,21 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I + static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev) + { + u32 region; ++ u8 enable; + +- pci_read_config_dword(dev, 0x40, ®ion); +- quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH4 ACPI/GPIO/TCO"); +- +- pci_read_config_dword(dev, 0x58, ®ion); +- quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH4 GPIO"); ++ pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); ++ if (enable & ICH4_ACPI_EN) { ++ pci_read_config_dword(dev, ICH_PMBASE, ®ion); ++ quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, ++ "ICH4 ACPI/GPIO/TCO"); ++ } ++ ++ pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); ++ if (enable & ICH4_GPIO_EN) { ++ pci_read_config_dword(dev, ICH4_GPIOBASE, ®ion); ++ quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES + 1, ++ "ICH4 GPIO"); ++ } + } + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); +@@ -562,12 +582,21 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I + static void __devinit ich6_lpc_acpi_gpio(struct pci_dev *dev) + { + u32 region; ++ u8 enable; + +- pci_read_config_dword(dev, 0x40, ®ion); +- quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH6 ACPI/GPIO/TCO"); +- +- pci_read_config_dword(dev, 0x48, ®ion); +- quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); ++ pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); ++ if (enable & ICH6_ACPI_EN) { ++ pci_read_config_dword(dev, ICH_PMBASE, ®ion); ++ quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, ++ "ICH6 ACPI/GPIO/TCO"); ++ } ++ ++ pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); ++ if (enable & ICH4_GPIO_EN) { ++ pci_read_config_dword(dev, ICH6_GPIOBASE, ®ion); ++ quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES + 1, ++ "ICH6 GPIO"); ++ } + } + + static void __devinit ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) +From 87e3dc3855430bd254370afc79f2ed92250f5b7c Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Mon, 28 Feb 2011 10:45:10 +0100 +Subject: PCI: do not create quirk I/O regions below PCIBIOS_MIN_IO for ICH + +From: Jiri Slaby + +commit 87e3dc3855430bd254370afc79f2ed92250f5b7c upstream. + +Some broken BIOSes on ICH4 chipset report an ACPI region which is in +conflict with legacy IDE ports when ACPI is disabled. Even though the +regions overlap, IDE ports are working correctly (we cannot find out +the decoding rules on chipsets). + +So the only problem is the reported region itself, if we don't reserve +the region in the quirk everything works as expected. + +This patch avoids reserving any quirk regions below PCIBIOS_MIN_IO +which is 0x1000. Some regions might be (and are by a fast google +query) below this border, but the only difference is that they won't +be reserved anymore. They should still work though the same as before. + +The conflicts look like (1f.0 is bridge, 1f.1 is IDE ctrl): +pci 0000:00:1f.1: address space collision: [io 0x0170-0x0177] conflicts with 0000:00:1f.0 [io 0x0100-0x017f] + +At 0x0100 a 128 bytes long ACPI region is reported in the quirk for +ICH4. ata_piix then fails to find disks because the IDE legacy ports +are zeroed: +ata_piix 0000:00:1f.1: device not available (can't reserve [io 0x0000-0x0007]) + +References: https://bugzilla.novell.com/show_bug.cgi?id=558740 +Signed-off-by: Jiri Slaby +Cc: Bjorn Helgaas +Cc: "David S. Miller" +Cc: Thomas Renninger +Signed-off-by: Jesse Barnes +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/quirks.c | 32 ++++++++++++++++++++++++-------- + 1 file changed, 24 insertions(+), 8 deletions(-) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -554,18 +554,30 @@ static void __devinit quirk_ich4_lpc_acp + u32 region; + u8 enable; + ++ /* ++ * The check for PCIBIOS_MIN_IO is to ensure we won't create a conflict ++ * with low legacy (and fixed) ports. We don't know the decoding ++ * priority and can't tell whether the legacy device or the one created ++ * here is really at that address. This happens on boards with broken ++ * BIOSes. ++ */ ++ + pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); + if (enable & ICH4_ACPI_EN) { + pci_read_config_dword(dev, ICH_PMBASE, ®ion); +- quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, +- "ICH4 ACPI/GPIO/TCO"); ++ region &= PCI_BASE_ADDRESS_IO_MASK; ++ if (region >= PCIBIOS_MIN_IO) ++ quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, ++ "ICH4 ACPI/GPIO/TCO"); + } + + pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); + if (enable & ICH4_GPIO_EN) { + pci_read_config_dword(dev, ICH4_GPIOBASE, ®ion); +- quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES + 1, +- "ICH4 GPIO"); ++ region &= PCI_BASE_ADDRESS_IO_MASK; ++ if (region >= PCIBIOS_MIN_IO) ++ quirk_io_region(dev, region, 64, ++ PCI_BRIDGE_RESOURCES + 1, "ICH4 GPIO"); + } + } + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); +@@ -587,15 +599,19 @@ static void __devinit ich6_lpc_acpi_gpio + pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); + if (enable & ICH6_ACPI_EN) { + pci_read_config_dword(dev, ICH_PMBASE, ®ion); +- quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, +- "ICH6 ACPI/GPIO/TCO"); ++ region &= PCI_BASE_ADDRESS_IO_MASK; ++ if (region >= PCIBIOS_MIN_IO) ++ quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, ++ "ICH6 ACPI/GPIO/TCO"); + } + + pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); + if (enable & ICH4_GPIO_EN) { + pci_read_config_dword(dev, ICH6_GPIOBASE, ®ion); +- quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES + 1, +- "ICH6 GPIO"); ++ region &= PCI_BASE_ADDRESS_IO_MASK; ++ if (region >= PCIBIOS_MIN_IO) ++ quirk_io_region(dev, region, 64, ++ PCI_BRIDGE_RESOURCES + 1, "ICH6 GPIO"); + } + } + +From 0f12a4e29368a9476076515881d9ef4e5876c6e2 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Thu, 13 Jan 2011 19:47:56 +0000 +Subject: PCI: sysfs: Fix failure path for addition of "vpd" attribute + +From: Ben Hutchings + +commit 0f12a4e29368a9476076515881d9ef4e5876c6e2 upstream. + +Commit 280c73d ("PCI: centralize the capabilities code in +pci-sysfs.c") changed the initialisation of the "rom" and "vpd" +attributes, and made the failure path for the "vpd" attribute +incorrect. We must free the new attribute structure (attr), but +instead we currently free dev->vpd->attr. That will normally be NULL, +resulting in a memory leak, but it might be a stale pointer, resulting +in a double-free. + +Found by inspection; compile-tested only. + +Signed-off-by: Ben Hutchings +Signed-off-by: Jesse Barnes +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci-sysfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -1088,7 +1088,7 @@ static int pci_create_capabilities_sysfs + attr->write = write_vpd_attr; + retval = sysfs_create_bin_file(&dev->dev.kobj, attr); + if (retval) { +- kfree(dev->vpd->attr); ++ kfree(attr); + return retval; + } + dev->vpd->attr = attr; +From 4a122c10fbfe9020df469f0f669da129c5757671 Mon Sep 17 00:00:00 2001 +From: Dan Rosenberg +Date: Thu, 17 Mar 2011 18:32:24 -0400 +Subject: ALSA: sound/pci/asihpi: check adapter index in hpi_ioctl + +From: Dan Rosenberg + +commit 4a122c10fbfe9020df469f0f669da129c5757671 upstream. + +The user-supplied index into the adapters array needs to be checked, or +an out-of-bounds kernel pointer could be accessed and used, leading to +potentially exploitable memory corruption. + +Signed-off-by: Dan Rosenberg +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/asihpi/hpioctl.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/sound/pci/asihpi/hpioctl.c ++++ b/sound/pci/asihpi/hpioctl.c +@@ -155,6 +155,11 @@ long asihpi_hpi_ioctl(struct file *file, + goto out; + } + ++ if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) { ++ err = -EINVAL; ++ goto out; ++ } ++ + pa = &adapters[hm->h.adapter_index]; + hr->h.size = 0; + if (hm->h.object == HPI_OBJ_SUBSYSTEM) { +From 98d21df431ad55281e1abf780f8d51e3391900b2 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 18 Mar 2011 07:31:53 +0100 +Subject: ALSA: aloop - Fix possible IRQ lock inversion + +From: Takashi Iwai + +commit 98d21df431ad55281e1abf780f8d51e3391900b2 upstream. + +loopback_pos_update() can be called in the timer callback, thus the lock +held should be irq-safe. Otherwise you'll get AB/BA deadlock together +with substream->self_group.lock. + +Reported-and-tested-by: Knut Petersen +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/drivers/aloop.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +--- a/sound/drivers/aloop.c ++++ b/sound/drivers/aloop.c +@@ -482,8 +482,9 @@ static unsigned int loopback_pos_update( + cable->streams[SNDRV_PCM_STREAM_CAPTURE]; + unsigned long delta_play = 0, delta_capt = 0; + unsigned int running; ++ unsigned long flags; + +- spin_lock(&cable->lock); ++ spin_lock_irqsave(&cable->lock, flags); + running = cable->running ^ cable->pause; + if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) { + delta_play = jiffies - dpcm_play->last_jiffies; +@@ -495,10 +496,8 @@ static unsigned int loopback_pos_update( + dpcm_capt->last_jiffies += delta_capt; + } + +- if (delta_play == 0 && delta_capt == 0) { +- spin_unlock(&cable->lock); +- return running; +- } ++ if (delta_play == 0 && delta_capt == 0) ++ goto unlock; + + if (delta_play > delta_capt) { + loopback_bytepos_update(dpcm_play, delta_play - delta_capt, +@@ -510,14 +509,14 @@ static unsigned int loopback_pos_update( + delta_capt = delta_play; + } + +- if (delta_play == 0 && delta_capt == 0) { +- spin_unlock(&cable->lock); +- return running; +- } ++ if (delta_play == 0 && delta_capt == 0) ++ goto unlock; ++ + /* note delta_capt == delta_play at this moment */ + loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY); + loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY); +- spin_unlock(&cable->lock); ++ unlock: ++ spin_unlock_irqrestore(&cable->lock, flags); + return running; + } + +From 4c1847e884efddcc3ede371f7839e5e65b25c34d Mon Sep 17 00:00:00 2001 +From: Przemyslaw Bruski +Date: Sun, 13 Mar 2011 16:18:56 +0100 +Subject: ALSA: ctxfi - Fix incorrect SPDIF status bit mask + +From: Przemyslaw Bruski + +commit 4c1847e884efddcc3ede371f7839e5e65b25c34d upstream. + +SPDIF status mask creation was incorrect. + +Signed-off-by: Przemyslaw Bruski +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/ctxfi/ctatc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/pci/ctxfi/ctatc.c ++++ b/sound/pci/ctxfi/ctatc.c +@@ -869,7 +869,7 @@ spdif_passthru_playback_setup(struct ct_ + mutex_lock(&atc->atc_mutex); + dao->ops->get_spos(dao, &status); + if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { +- status &= ((~IEC958_AES3_CON_FS) << 24); ++ status &= ~(IEC958_AES3_CON_FS << 24); + status |= (iec958_con_fs << 24); + dao->ops->set_spos(dao, status); + dao->ops->commit_write(dao); +From f164753a263bfd2daaf3e0273b179de7e099c57d Mon Sep 17 00:00:00 2001 +From: Przemyslaw Bruski +Date: Sun, 13 Mar 2011 16:18:57 +0100 +Subject: ALSA: ctxfi - Fix SPDIF status retrieval + +From: Przemyslaw Bruski + +commit f164753a263bfd2daaf3e0273b179de7e099c57d upstream. + +SDPIF status retrieval always returned the default settings instead of +the actual ones. + +Signed-off-by: Przemyslaw Bruski +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/ctxfi/ctmixer.c | 19 +++++-------------- + 1 file changed, 5 insertions(+), 14 deletions(-) + +--- a/sound/pci/ctxfi/ctmixer.c ++++ b/sound/pci/ctxfi/ctmixer.c +@@ -566,19 +566,6 @@ static int ct_spdif_get_mask(struct snd_ + return 0; + } + +-static int ct_spdif_default_get(struct snd_kcontrol *kcontrol, +- struct snd_ctl_elem_value *ucontrol) +-{ +- unsigned int status = SNDRV_PCM_DEFAULT_CON_SPDIF; +- +- ucontrol->value.iec958.status[0] = (status >> 0) & 0xff; +- ucontrol->value.iec958.status[1] = (status >> 8) & 0xff; +- ucontrol->value.iec958.status[2] = (status >> 16) & 0xff; +- ucontrol->value.iec958.status[3] = (status >> 24) & 0xff; +- +- return 0; +-} +- + static int ct_spdif_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { +@@ -586,6 +573,10 @@ static int ct_spdif_get(struct snd_kcont + unsigned int status; + + atc->spdif_out_get_status(atc, &status); ++ ++ if (status == 0) ++ status = SNDRV_PCM_DEFAULT_CON_SPDIF; ++ + ucontrol->value.iec958.status[0] = (status >> 0) & 0xff; + ucontrol->value.iec958.status[1] = (status >> 8) & 0xff; + ucontrol->value.iec958.status[2] = (status >> 16) & 0xff; +@@ -629,7 +620,7 @@ static struct snd_kcontrol_new iec958_de + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), + .count = 1, + .info = ct_spdif_info, +- .get = ct_spdif_default_get, ++ .get = ct_spdif_get, + .put = ct_spdif_put, + .private_value = MIXER_IEC958_DEFAULT + }; +From efed5f26664f93991c929d5bb343e65f900d72bc Mon Sep 17 00:00:00 2001 +From: Przemyslaw Bruski +Date: Sun, 13 Mar 2011 16:18:58 +0100 +Subject: ALSA: ctxfi - Clear input settings before initialization + +From: Przemyslaw Bruski + +commit efed5f26664f93991c929d5bb343e65f900d72bc upstream. + +Clear input settings before initialization. + +Signed-off-by: Przemyslaw Bruski +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/ctxfi/ctdaio.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/pci/ctxfi/ctdaio.c ++++ b/sound/pci/ctxfi/ctdaio.c +@@ -176,6 +176,7 @@ static int dao_set_left_input(struct dao + if (!entry) + return -ENOMEM; + ++ dao->ops->clear_left_input(dao); + /* Program master and conjugate resources */ + input->ops->master(input); + daio->rscl.ops->master(&daio->rscl); +@@ -204,6 +205,7 @@ static int dao_set_right_input(struct da + if (!entry) + return -ENOMEM; + ++ dao->ops->clear_right_input(dao); + /* Program master and conjugate resources */ + input->ops->master(input); + daio->rscr.ops->master(&daio->rscr); +From 64c25a92e865f06ad8782fbdaa1e2a97d50acf73 Mon Sep 17 00:00:00 2001 +From: Vasily Khoruzhick +Date: Fri, 11 Mar 2011 11:05:38 +0200 +Subject: ASoC: PXA: Z2: Fix codec pin name + +From: Vasily Khoruzhick + +commit 64c25a92e865f06ad8782fbdaa1e2a97d50acf73 upstream. + +MONO was renamed to MONO1. + +Signed-off-by: Vasily Khoruzhick +Acked-by: Liam Girdwood +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/pxa/z2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/pxa/z2.c ++++ b/sound/soc/pxa/z2.c +@@ -147,7 +147,7 @@ static int z2_wm8750_init(struct snd_soc + snd_soc_dapm_disable_pin(dapm, "LINPUT3"); + snd_soc_dapm_disable_pin(dapm, "RINPUT3"); + snd_soc_dapm_disable_pin(dapm, "OUT3"); +- snd_soc_dapm_disable_pin(dapm, "MONO"); ++ snd_soc_dapm_disable_pin(dapm, "MONO1"); + + /* Add z2 specific widgets */ + snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, +From 904f0bc482201fa86e75c330d79dfd11be494cf8 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 2 Mar 2011 15:52:51 -0800 +Subject: [SCSI] target: Fix volume size misreporting for volumes > 2TB + +From: Nicholas Bellinger + +commit 904f0bc482201fa86e75c330d79dfd11be494cf8 upstream. + +the target infrastructure fails to send the correct conventional size +to READ_CAPACITY that force a retry with READ_CAPACITY_16, which reads +the capacity for devices > 2TB. Fix by adding the correct return to +trigger RC(16). + +Reported-by: Ben Jarvis +Signed-off-by: Signed-off-by: Nicholas A. Bellinger +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_cdb.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -667,7 +667,13 @@ target_emulate_readcapacity(struct se_cm + { + struct se_device *dev = SE_DEV(cmd); + unsigned char *buf = cmd->t_task->t_task_buf; +- u32 blocks = dev->transport->get_blocks(dev); ++ unsigned long long blocks_long = dev->transport->get_blocks(dev); ++ u32 blocks; ++ ++ if (blocks_long >= 0x00000000ffffffff) ++ blocks = 0xffffffff; ++ else ++ blocks = (u32)blocks_long; + + buf[0] = (blocks >> 24) & 0xff; + buf[1] = (blocks >> 16) & 0xff; +From ed0f36bc5719b25659b637f80ceea85494b84502 Mon Sep 17 00:00:00 2001 +From: Joseph Gruher +Date: Wed, 5 Jan 2011 16:00:21 -0500 +Subject: [SCSI] scsi_dh_alua: fix deadlock in stpg_endio + +From: Joseph Gruher + +commit ed0f36bc5719b25659b637f80ceea85494b84502 upstream. + +The use of blk_execute_rq_nowait() implies __blk_put_request() is needed +in stpg_endio() rather than blk_put_request() -- blk_finish_request() is +called with queue lock already held. + +Signed-off-by: Joseph Gruher +Signed-off-by: Ilgu Hong +Signed-off-by: Mike Snitzer +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/device_handler/scsi_dh_alua.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/device_handler/scsi_dh_alua.c ++++ b/drivers/scsi/device_handler/scsi_dh_alua.c +@@ -285,7 +285,8 @@ static void stpg_endio(struct request *r + print_alua_state(h->state)); + } + done: +- blk_put_request(req); ++ req->end_io_data = NULL; ++ __blk_put_request(req->q, req); + if (h->callback_fn) { + h->callback_fn(h->callback_data, err); + h->callback_fn = h->callback_data = NULL; +From e020c6800c9621a77223bf2c1ff68180e41e8ebf Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Tue, 15 Mar 2011 19:56:30 -0400 +Subject: SUNRPC: Ensure we always run the tk_callback before tk_action + +From: Trond Myklebust + +commit e020c6800c9621a77223bf2c1ff68180e41e8ebf upstream. + +This fixes a race in which the task->tk_callback() puts the rpc_task +to sleep, setting a new callback. Under certain circumstances, the current +code may end up executing the task->tk_action before it gets round to the +callback. + +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/sched.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -637,14 +637,12 @@ static void __rpc_execute(struct rpc_tas + save_callback = task->tk_callback; + task->tk_callback = NULL; + save_callback(task); +- } +- +- /* +- * Perform the next FSM step. +- * tk_action may be NULL when the task has been killed +- * by someone else. +- */ +- if (!RPC_IS_QUEUED(task)) { ++ } else { ++ /* ++ * Perform the next FSM step. ++ * tk_action may be NULL when the task has been killed ++ * by someone else. ++ */ + if (task->tk_action == NULL) + break; + task->tk_action(task); +From 8e26de238fd794c8ea56a5c98bf67c40cfeb051d Mon Sep 17 00:00:00 2001 +From: Stanislav Kinsbursky +Date: Thu, 17 Mar 2011 18:54:23 +0300 +Subject: RPC: killing RPC tasks races fixed + +From: Stanislav Kinsbursky + +commit 8e26de238fd794c8ea56a5c98bf67c40cfeb051d upstream. + +RPC task RPC_TASK_QUEUED bit is set must be checked before trying to wake up +task rpc_killall_tasks() because task->tk_waitqueue can not be set (equal to +NULL). +Also, as Trond Myklebust mentioned, such approach (instead of checking +tk_waitqueue to NULL) allows us to "optimise away the call to +rpc_wake_up_queued_task() altogether for those +tasks that aren't queued". + +Here is an example of dereferencing of tk_waitqueue equal to NULL: + +CPU 0 CPU 1 CPU 2 +-------------------- --------------------- -------------------------- +nfs4_run_open_task +rpc_run_task +rpc_execute +rpc_set_active +rpc_make_runnable +(waiting) + rpc_async_schedule + nfs4_open_prepare + nfs_wait_on_sequence + nfs_umount_begin + rpc_killall_tasks + rpc_wake_up_task + rpc_wake_up_queued_task + spin_lock(tk_waitqueue == NULL) + BUG() + rpc_sleep_on + spin_lock(&q->lock) + __rpc_sleep_on + task->tk_waitqueue = q + +Signed-off-by: Stanislav Kinsbursky +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/clnt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -436,7 +436,9 @@ void rpc_killall_tasks(struct rpc_clnt * + if (!(rovr->tk_flags & RPC_TASK_KILLED)) { + rovr->tk_flags |= RPC_TASK_KILLED; + rpc_exit(rovr, -EIO); +- rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr); ++ if (RPC_IS_QUEUED(rovr)) ++ rpc_wake_up_queued_task(rovr->tk_waitqueue, ++ rovr); + } + } + spin_unlock(&clnt->cl_lock); +From 91b2f482e62ad0d444222253026a5cbca28c4ab9 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Mon, 7 Mar 2011 21:27:08 +0100 +Subject: perf: Fix the software events state check + +From: Frederic Weisbecker + +commit 91b2f482e62ad0d444222253026a5cbca28c4ab9 upstream. + +Fix the mistakenly inverted check of events state. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Peter Zijlstra +Cc: Arnaldo Carvalho de Melo +Cc: Paul Mackerras +Cc: Stephane Eranian +LKML-Reference: <1299529629-18280-1-git-send-email-fweisbec@gmail.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/perf_event.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/perf_event.c ++++ b/kernel/perf_event.c +@@ -4567,7 +4567,7 @@ static int perf_exclude_event(struct per + struct pt_regs *regs) + { + if (event->hw.state & PERF_HES_STOPPED) +- return 0; ++ return 1; + + if (regs) { + if (event->attr.exclude_user && user_mode(regs)) +From a0f7d0f7fc02465bb9758501f611f63381792996 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Mon, 7 Mar 2011 21:27:09 +0100 +Subject: perf: Handle stopped state with tracepoints + +From: Frederic Weisbecker + +commit a0f7d0f7fc02465bb9758501f611f63381792996 upstream. + +We toggle the state from start and stop callbacks but actually +don't check it when the event triggers. Do it so that +these callbacks actually work. + +Signed-off-by: Frederic Weisbecker +Cc: Arnaldo Carvalho de Melo +Cc: Paul Mackerras +Cc: Stephane Eranian +Signed-off-by: Peter Zijlstra +LKML-Reference: <1299529629-18280-2-git-send-email-fweisbec@gmail.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/perf_event.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/perf_event.c ++++ b/kernel/perf_event.c +@@ -4923,6 +4923,8 @@ static int perf_tp_event_match(struct pe + struct perf_sample_data *data, + struct pt_regs *regs) + { ++ if (event->hw.state & PERF_HES_STOPPED) ++ return 0; + /* + * All tracepoints are from kernel-space. + */ +From 0837e3242c73566fc1c0196b4ec61779c25ffc93 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Wed, 9 Mar 2011 14:38:42 +1100 +Subject: perf, powerpc: Handle events that raise an exception without overflowing + +From: Anton Blanchard + +commit 0837e3242c73566fc1c0196b4ec61779c25ffc93 upstream. + +Events on POWER7 can roll back if a speculative event doesn't +eventually complete. Unfortunately in some rare cases they will +raise a performance monitor exception. We need to catch this to +ensure we reset the PMC. In all cases the PMC will be 256 or less +cycles from overflow. + +Signed-off-by: Anton Blanchard +Signed-off-by: Peter Zijlstra +LKML-Reference: <20110309143842.6c22845e@kryten> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/reg.h | 1 + + arch/powerpc/kernel/perf_event.c | 24 +++++++++++++++++++++++- + 2 files changed, 24 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/include/asm/reg.h ++++ b/arch/powerpc/include/asm/reg.h +@@ -880,6 +880,7 @@ + #define PV_970 0x0039 + #define PV_POWER5 0x003A + #define PV_POWER5p 0x003B ++#define PV_POWER7 0x003F + #define PV_970FX 0x003C + #define PV_630 0x0040 + #define PV_630p 0x0041 +--- a/arch/powerpc/kernel/perf_event.c ++++ b/arch/powerpc/kernel/perf_event.c +@@ -1269,6 +1269,28 @@ unsigned long perf_instruction_pointer(s + return ip; + } + ++static bool pmc_overflow(unsigned long val) ++{ ++ if ((int)val < 0) ++ return true; ++ ++ /* ++ * Events on POWER7 can roll back if a speculative event doesn't ++ * eventually complete. Unfortunately in some rare cases they will ++ * raise a performance monitor exception. We need to catch this to ++ * ensure we reset the PMC. In all cases the PMC will be 256 or less ++ * cycles from overflow. ++ * ++ * We only do this if the first pass fails to find any overflowing ++ * PMCs because a user might set a period of less than 256 and we ++ * don't want to mistakenly reset them. ++ */ ++ if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256)) ++ return true; ++ ++ return false; ++} ++ + /* + * Performance monitor interrupt stuff + */ +@@ -1316,7 +1338,7 @@ static void perf_event_interrupt(struct + if (is_limited_pmc(i + 1)) + continue; + val = read_pmc(i + 1); +- if ((int)val < 0) ++ if (pmc_overflow(val)) + write_pmc(i + 1, 0); + } + } +From 58d406ed6a5f1ca4bc1dba5390b718c67847fa5f Mon Sep 17 00:00:00 2001 +From: Josh Hunt +Date: Tue, 15 Mar 2011 19:16:40 -0700 +Subject: perf tools: Version incorrect with some versions of grep + +From: Josh Hunt + +commit 58d406ed6a5f1ca4bc1dba5390b718c67847fa5f upstream. + +Some versions of grep don't treat '\s' properly. When building perf on such +systems and using a kernel tarball the perf version is unable to be determined +from the main kernel Makefile and the user is left with a version of '..'. +Replacing the use of '\s' with '[[:space:]]', which should work in all grep +versions, gives a usable version number. + +Reported-by: Tapan Dhimant +Cc: Ingo Molnar +Cc: Paul Mackerras +Cc: Peter Zijlstra +Cc: Tapan Dhimant +Cc: linux-kernel@vger.kernel.org +LKML-Reference: <1300241800-30281-1-git-send-email-johunt@akamai.com> +Signed-off-by: Josh Hunt +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/PERF-VERSION-GEN | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/tools/perf/util/PERF-VERSION-GEN ++++ b/tools/perf/util/PERF-VERSION-GEN +@@ -23,10 +23,10 @@ if test -d ../../.git -o -f ../../.git & + then + VN=$(echo "$VN" | sed -e 's/-/./g'); + else +- eval `grep '^VERSION\s*=' ../../Makefile|tr -d ' '` +- eval `grep '^PATCHLEVEL\s*=' ../../Makefile|tr -d ' '` +- eval `grep '^SUBLEVEL\s*=' ../../Makefile|tr -d ' '` +- eval `grep '^EXTRAVERSION\s*=' ../../Makefile|tr -d ' '` ++ eval $(grep '^VERSION[[:space:]]*=' ../../Makefile|tr -d ' ') ++ eval $(grep '^PATCHLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ') ++ eval $(grep '^SUBLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ') ++ eval $(grep '^EXTRAVERSION[[:space:]]*=' ../../Makefile|tr -d ' ') + + VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}" + fi +From d7433142b63d727b5a217c37b1a1468b116a9771 Mon Sep 17 00:00:00 2001 +From: Eric Sandeen +Date: Fri, 4 Mar 2011 16:04:08 -0600 +Subject: ext3: Always set dx_node's fake_dirent explicitly. + +From: Eric Sandeen + +commit d7433142b63d727b5a217c37b1a1468b116a9771 upstream. + +(crossport of 1f7bebb9e911d870fa8f997ddff838e82b5715ea +by Andreas Schlick ) + +When ext3_dx_add_entry() has to split an index node, it has to ensure that +name_len of dx_node's fake_dirent is also zero, because otherwise e2fsck +won't recognise it as an intermediate htree node and consider the htree to +be corrupted. + +Signed-off-by: Eric Sandeen +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext3/namei.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext3/namei.c ++++ b/fs/ext3/namei.c +@@ -1540,8 +1540,8 @@ static int ext3_dx_add_entry(handle_t *h + goto cleanup; + node2 = (struct dx_node *)(bh2->b_data); + entries2 = node2->entries; ++ memset(&node2->fake, 0, sizeof(struct fake_dirent)); + node2->fake.rec_len = ext3_rec_len_to_disk(sb->s_blocksize); +- node2->fake.inode = 0; + BUFFER_TRACE(frame->bh, "get_write_access"); + err = ext3_journal_get_write_access(handle, frame->bh); + if (err) +From e6cd1e07a185d5f9b0aa75e020df02d3c1c44940 Mon Sep 17 00:00:00 2001 +From: Milton Miller +Date: Tue, 15 Mar 2011 13:27:16 -0600 +Subject: call_function_many: fix list delete vs add race + +From: Milton Miller + +commit e6cd1e07a185d5f9b0aa75e020df02d3c1c44940 upstream. + +Peter pointed out there was nothing preventing the list_del_rcu in +smp_call_function_interrupt from running before the list_add_rcu in +smp_call_function_many. + +Fix this by not setting refs until we have gotten the lock for the list. +Take advantage of the wmb in list_add_rcu to save an explicit additional +one. + +I tried to force this race with a udelay before the lock & list_add and +by mixing all 64 online cpus with just 3 random cpus in the mask, but +was unsuccessful. Still, inspection shows a valid race, and the fix is +a extension of the existing protection window in the current code. + +Reported-by: Peter Zijlstra +Signed-off-by: Milton Miller +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/smp.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/kernel/smp.c ++++ b/kernel/smp.c +@@ -491,14 +491,15 @@ void smp_call_function_many(const struct + cpumask_clear_cpu(this_cpu, data->cpumask); + + /* +- * To ensure the interrupt handler gets an complete view +- * we order the cpumask and refs writes and order the read +- * of them in the interrupt handler. In addition we may +- * only clear our own cpu bit from the mask. ++ * We reuse the call function data without waiting for any grace ++ * period after some other cpu removes it from the global queue. ++ * This means a cpu might find our data block as it is writen. ++ * The interrupt handler waits until it sees refs filled out ++ * while its cpu mask bit is set; here we may only clear our ++ * own cpu mask bit, and must wait to set refs until we are sure ++ * previous writes are complete and we have obtained the lock to ++ * add the element to the queue. + */ +- smp_wmb(); +- +- atomic_set(&data->refs, cpumask_weight(data->cpumask)); + + raw_spin_lock_irqsave(&call_function.lock, flags); + /* +@@ -507,6 +508,11 @@ void smp_call_function_many(const struct + * will not miss any other list entries: + */ + list_add_rcu(&data->csd.list, &call_function.queue); ++ /* ++ * We rely on the wmb() in list_add_rcu to order the writes ++ * to func, data, and cpumask before this write to refs. ++ */ ++ atomic_set(&data->refs, cpumask_weight(data->cpumask)); + raw_spin_unlock_irqrestore(&call_function.lock, flags); + + /* +From 45a5791920ae643eafc02e2eedef1a58e341b736 Mon Sep 17 00:00:00 2001 +From: Milton Miller +Date: Tue, 15 Mar 2011 13:27:16 -0600 +Subject: call_function_many: add missing ordering + +From: Milton Miller + +commit 45a5791920ae643eafc02e2eedef1a58e341b736 upstream. + +Paul McKenney's review pointed out two problems with the barriers in the +2.6.38 update to the smp call function many code. + +First, a barrier that would force the func and info members of data to +be visible before their consumption in the interrupt handler was +missing. This can be solved by adding a smp_wmb between setting the +func and info members and setting setting the cpumask; this will pair +with the existing and required smp_rmb ordering the cpumask read before +the read of refs. This placement avoids the need a second smp_rmb in +the interrupt handler which would be executed on each of the N cpus +executing the call request. (I was thinking this barrier was present +but was not). + +Second, the previous write to refs (establishing the zero that we the +interrupt handler was testing from all cpus) was performed by a third +party cpu. This would invoke transitivity which, as a recient or +concurrent addition to memory-barriers.txt now explicitly states, would +require a full smp_mb(). + +However, we know the cpumask will only be set by one cpu (the data +owner) and any preivous iteration of the mask would have cleared by the +reading cpu. By redundantly writing refs to 0 on the owning cpu before +the smp_wmb, the write to refs will follow the same path as the writes +that set the cpumask, which in turn allows us to keep the barrier in the +interrupt handler a smp_rmb instead of promoting it to a smp_mb (which +will be be executed by N cpus for each of the possible M elements on the +list). + +I moved and expanded the comment about our (ab)use of the rcu list +primitives for the concurrent walk earlier into this function. I +considered moving the first two paragraphs to the queue list head and +lock, but felt it would have been too disconected from the code. + +Cc: Paul McKinney +Signed-off-by: Milton Miller +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/smp.c | 46 +++++++++++++++++++++++++++++++++------------- + 1 file changed, 33 insertions(+), 13 deletions(-) + +--- a/kernel/smp.c ++++ b/kernel/smp.c +@@ -483,23 +483,42 @@ void smp_call_function_many(const struct + + data = &__get_cpu_var(cfd_data); + csd_lock(&data->csd); +- BUG_ON(atomic_read(&data->refs) || !cpumask_empty(data->cpumask)); + +- data->csd.func = func; +- data->csd.info = info; +- cpumask_and(data->cpumask, mask, cpu_online_mask); +- cpumask_clear_cpu(this_cpu, data->cpumask); ++ /* This BUG_ON verifies our reuse assertions and can be removed */ ++ BUG_ON(atomic_read(&data->refs) || !cpumask_empty(data->cpumask)); + + /* ++ * The global call function queue list add and delete are protected ++ * by a lock, but the list is traversed without any lock, relying ++ * on the rcu list add and delete to allow safe concurrent traversal. + * We reuse the call function data without waiting for any grace + * period after some other cpu removes it from the global queue. +- * This means a cpu might find our data block as it is writen. +- * The interrupt handler waits until it sees refs filled out +- * while its cpu mask bit is set; here we may only clear our +- * own cpu mask bit, and must wait to set refs until we are sure +- * previous writes are complete and we have obtained the lock to +- * add the element to the queue. ++ * This means a cpu might find our data block as it is being ++ * filled out. ++ * ++ * We hold off the interrupt handler on the other cpu by ++ * ordering our writes to the cpu mask vs our setting of the ++ * refs counter. We assert only the cpu owning the data block ++ * will set a bit in cpumask, and each bit will only be cleared ++ * by the subject cpu. Each cpu must first find its bit is ++ * set and then check that refs is set indicating the element is ++ * ready to be processed, otherwise it must skip the entry. ++ * ++ * On the previous iteration refs was set to 0 by another cpu. ++ * To avoid the use of transitivity, set the counter to 0 here ++ * so the wmb will pair with the rmb in the interrupt handler. + */ ++ atomic_set(&data->refs, 0); /* convert 3rd to 1st party write */ ++ ++ data->csd.func = func; ++ data->csd.info = info; ++ ++ /* Ensure 0 refs is visible before mask. Also orders func and info */ ++ smp_wmb(); ++ ++ /* We rely on the "and" being processed before the store */ ++ cpumask_and(data->cpumask, mask, cpu_online_mask); ++ cpumask_clear_cpu(this_cpu, data->cpumask); + + raw_spin_lock_irqsave(&call_function.lock, flags); + /* +@@ -509,8 +528,9 @@ void smp_call_function_many(const struct + */ + list_add_rcu(&data->csd.list, &call_function.queue); + /* +- * We rely on the wmb() in list_add_rcu to order the writes +- * to func, data, and cpumask before this write to refs. ++ * We rely on the wmb() in list_add_rcu to complete our writes ++ * to the cpumask before this write to refs, which indicates ++ * data is on the list and is ready to be processed. + */ + atomic_set(&data->refs, cpumask_weight(data->cpumask)); + raw_spin_unlock_irqrestore(&call_function.lock, flags); +From 723aae25d5cdb09962901d36d526b44d4be1051c Mon Sep 17 00:00:00 2001 +From: Milton Miller +Date: Tue, 15 Mar 2011 13:27:17 -0600 +Subject: smp_call_function_many: handle concurrent clearing of mask + +From: Milton Miller + +commit 723aae25d5cdb09962901d36d526b44d4be1051c upstream. + +Mike Galbraith reported finding a lockup ("perma-spin bug") where the +cpumask passed to smp_call_function_many was cleared by other cpu(s) +while a cpu was preparing its call_data block, resulting in no cpu to +clear the last ref and unlock the block. + +Having cpus clear their bit asynchronously could be useful on a mask of +cpus that might have a translation context, or cpus that need a push to +complete an rcu window. + +Instead of adding a BUG_ON and requiring yet another cpumask copy, just +detect the race and handle it. + +Note: arch_send_call_function_ipi_mask must still handle an empty +cpumask because the data block is globally visible before the that arch +callback is made. And (obviously) there are no guarantees to which cpus +are notified if the mask is changed during the call; only cpus that were +online and had their mask bit set during the whole call are guaranteed +to be called. + +Reported-by: Mike Galbraith +Reported-by: Jan Beulich +Acked-by: Jan Beulich +Signed-off-by: Milton Miller +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/smp.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/kernel/smp.c ++++ b/kernel/smp.c +@@ -450,7 +450,7 @@ void smp_call_function_many(const struct + { + struct call_function_data *data; + unsigned long flags; +- int cpu, next_cpu, this_cpu = smp_processor_id(); ++ int refs, cpu, next_cpu, this_cpu = smp_processor_id(); + + /* + * Can deadlock when called with interrupts disabled. +@@ -461,7 +461,7 @@ void smp_call_function_many(const struct + WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() + && !oops_in_progress && !early_boot_irqs_disabled); + +- /* So, what's a CPU they want? Ignoring this one. */ ++ /* Try to fastpath. So, what's a CPU they want? Ignoring this one. */ + cpu = cpumask_first_and(mask, cpu_online_mask); + if (cpu == this_cpu) + cpu = cpumask_next_and(cpu, mask, cpu_online_mask); +@@ -519,6 +519,13 @@ void smp_call_function_many(const struct + /* We rely on the "and" being processed before the store */ + cpumask_and(data->cpumask, mask, cpu_online_mask); + cpumask_clear_cpu(this_cpu, data->cpumask); ++ refs = cpumask_weight(data->cpumask); ++ ++ /* Some callers race with other cpus changing the passed mask */ ++ if (unlikely(!refs)) { ++ csd_unlock(&data->csd); ++ return; ++ } + + raw_spin_lock_irqsave(&call_function.lock, flags); + /* +@@ -532,7 +539,7 @@ void smp_call_function_many(const struct + * to the cpumask before this write to refs, which indicates + * data is on the list and is ready to be processed. + */ +- atomic_set(&data->refs, cpumask_weight(data->cpumask)); ++ atomic_set(&data->refs, refs); + raw_spin_unlock_irqrestore(&call_function.lock, flags); + + /* +From 4981d01eada5354d81c8929d5b2836829ba3df7b Mon Sep 17 00:00:00 2001 +From: Shaohua Li +Date: Wed, 16 Mar 2011 11:37:29 +0800 +Subject: x86: Flush TLB if PGD entry is changed in i386 PAE mode + +From: Shaohua Li + +commit 4981d01eada5354d81c8929d5b2836829ba3df7b upstream. + +According to intel CPU manual, every time PGD entry is changed in i386 PAE +mode, we need do a full TLB flush. Current code follows this and there is +comment for this too in the code. + +But current code misses the multi-threaded case. A changed page table +might be used by several CPUs, every such CPU should flush TLB. Usually +this isn't a problem, because we prepopulate all PGD entries at process +fork. But when the process does munmap and follows new mmap, this issue +will be triggered. + +When it happens, some CPUs keep doing page faults: + + http://marc.info/?l=linux-kernel&m=129915020508238&w=2 + +Reported-by: Yasunori Goto +Tested-by: Yasunori Goto +Reviewed-by: Rik van Riel +Signed-off-by: Shaohua Li +Cc: Mallick Asit K +Cc: Linus Torvalds +Cc: Andrew Morton +Cc: linux-mm +LKML-Reference: <1300246649.2337.95.camel@sli10-conroe> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/pgtable-3level.h | 11 +++-------- + arch/x86/mm/pgtable.c | 3 +-- + 2 files changed, 4 insertions(+), 10 deletions(-) + +--- a/arch/x86/include/asm/pgtable-3level.h ++++ b/arch/x86/include/asm/pgtable-3level.h +@@ -69,8 +69,6 @@ static inline void native_pmd_clear(pmd_ + + static inline void pud_clear(pud_t *pudp) + { +- unsigned long pgd; +- + set_pud(pudp, __pud(0)); + + /* +@@ -79,13 +77,10 @@ static inline void pud_clear(pud_t *pudp + * section 8.1: in PAE mode we explicitly have to flush the + * TLB via cr3 if the top-level pgd is changed... + * +- * Make sure the pud entry we're updating is within the +- * current pgd to avoid unnecessary TLB flushes. ++ * Currently all places where pud_clear() is called either have ++ * flush_tlb_mm() followed or don't need TLB flush (x86_64 code or ++ * pud_clear_bad()), so we don't need TLB flush here. + */ +- pgd = read_cr3(); +- if (__pa(pudp) >= pgd && __pa(pudp) < +- (pgd + sizeof(pgd_t)*PTRS_PER_PGD)) +- write_cr3(pgd); + } + + #ifdef CONFIG_SMP +--- a/arch/x86/mm/pgtable.c ++++ b/arch/x86/mm/pgtable.c +@@ -168,8 +168,7 @@ void pud_populate(struct mm_struct *mm, + * section 8.1: in PAE mode we explicitly have to flush the + * TLB via cr3 if the top-level pgd is changed... + */ +- if (mm == current->active_mm) +- write_cr3(read_cr3()); ++ flush_tlb_mm(mm); + } + #else /* !CONFIG_X86_PAE */ + +From 0ae43810976bc969ee158510c4acbe70ed136e61 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 11 Mar 2011 00:27:34 -0800 +Subject: HID: ACRUX - activate the device immediately after binding + +From: Dmitry Torokhov + +commit 0ae43810976bc969ee158510c4acbe70ed136e61 upstream. + +This device does not tolerate delayed opening and goes into a coma if +we try to that. Ubuntu even has a crutch for udev that opened the device +upon seeing it for the first time, but it did not work if we happened to +boot with the device attached, since by the time userspace got around +opening the device it was too late. Let's start the device immediately +to deal with this issue. + +Reported-by: Sergei Kolzun +Signed-off-by: Dmitry Torokhov +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/Kconfig | 10 ++++++++-- + drivers/hid/Makefile | 2 +- + drivers/hid/hid-axff.c | 31 ++++++++++++++++++++++++++++--- + drivers/hid/hid-core.c | 2 -- + 4 files changed, 37 insertions(+), 8 deletions(-) + +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -68,9 +68,15 @@ config HID_A4TECH + ---help--- + Support for A4 tech X5 and WOP-35 / Trust 450L mice. + +-config HID_ACRUX_FF +- tristate "ACRUX force feedback" ++config HID_ACRUX ++ tristate "ACRUX game controller support" + depends on USB_HID ++ ---help--- ++ Say Y here if you want to enable support for ACRUX game controllers. ++ ++config HID_ACRUX_FF ++ tristate "ACRUX force feedback support" ++ depends on HID_ACRUX + select INPUT_FF_MEMLESS + ---help--- + Say Y here if you want to enable force feedback support for ACRUX +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -27,7 +27,7 @@ endif + + obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o + obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o +-obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o ++obj-$(CONFIG_HID_ACRUX) += hid-axff.o + obj-$(CONFIG_HID_APPLE) += hid-apple.o + obj-$(CONFIG_HID_BELKIN) += hid-belkin.o + obj-$(CONFIG_HID_CANDO) += hid-cando.o +--- a/drivers/hid/hid-axff.c ++++ b/drivers/hid/hid-axff.c +@@ -33,6 +33,8 @@ + #include + + #include "hid-ids.h" ++ ++#ifdef CONFIG_HID_ACRUX_FF + #include "usbhid/usbhid.h" + + struct axff_device { +@@ -109,6 +111,12 @@ err_free_mem: + kfree(axff); + return error; + } ++#else ++static inline int axff_init(struct hid_device *hid) ++{ ++ return 0; ++} ++#endif + + static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id) + { +@@ -139,9 +147,25 @@ static int ax_probe(struct hid_device *h + error); + } + ++ /* ++ * We need to start polling device right away, otherwise ++ * it will go into a coma. ++ */ ++ error = hid_hw_open(hdev); ++ if (error) { ++ dev_err(&hdev->dev, "hw open failed\n"); ++ return error; ++ } ++ + return 0; + } + ++static void ax_remove(struct hid_device *hdev) ++{ ++ hid_hw_close(hdev); ++ hid_hw_stop(hdev); ++} ++ + static const struct hid_device_id ax_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), }, + { } +@@ -149,9 +173,10 @@ static const struct hid_device_id ax_dev + MODULE_DEVICE_TABLE(hid, ax_devices); + + static struct hid_driver ax_driver = { +- .name = "acrux", +- .id_table = ax_devices, +- .probe = ax_probe, ++ .name = "acrux", ++ .id_table = ax_devices, ++ .probe = ax_probe, ++ .remove = ax_remove, + }; + + static int __init ax_init(void) +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1256,9 +1256,7 @@ static const struct hid_device_id hid_ha + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, +-#if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE) + { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, +-#endif + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, +From f635bd11c8d332d917fb9a4cad3071b2357d5b2a Mon Sep 17 00:00:00 2001 +From: Henrik Rydberg +Date: Thu, 24 Feb 2011 19:30:59 +0100 +Subject: HID: Do not create input devices for feature reports + +From: Henrik Rydberg + +commit f635bd11c8d332d917fb9a4cad3071b2357d5b2a upstream. + +When the multi input quirk is set, there is a new input device +created for every feature report. Since the idea is to present +features per hid device, not per input device, revert back to +the original report loop and change the feature_mapping() callback +to not take the input device as argument. + +Signed-off-by: Henrik Rydberg +Tested-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-input.c | 30 +++++++++++++++++++++--------- + drivers/hid/hid-multitouch.c | 2 +- + include/linux/hid.h | 2 +- + 3 files changed, 23 insertions(+), 11 deletions(-) + +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -290,14 +290,6 @@ static void hidinput_configure_usage(str + goto ignore; + } + +- if (field->report_type == HID_FEATURE_REPORT) { +- if (device->driver->feature_mapping) { +- device->driver->feature_mapping(device, hidinput, field, +- usage); +- } +- goto ignore; +- } +- + if (device->driver->input_mapping) { + int ret = device->driver->input_mapping(device, hidinput, field, + usage, &bit, &max); +@@ -835,6 +827,24 @@ static void hidinput_close(struct input_ + hid_hw_close(hid); + } + ++static void report_features(struct hid_device *hid) ++{ ++ struct hid_driver *drv = hid->driver; ++ struct hid_report_enum *rep_enum; ++ struct hid_report *rep; ++ int i, j; ++ ++ if (!drv->feature_mapping) ++ return; ++ ++ rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; ++ list_for_each_entry(rep, &rep_enum->report_list, list) ++ for (i = 0; i < rep->maxfield; i++) ++ for (j = 0; j < rep->field[i]->maxusage; j++) ++ drv->feature_mapping(hid, rep->field[i], ++ rep->field[i]->usage + j); ++} ++ + /* + * Register the input device; print a message. + * Configure the input layer interface +@@ -863,7 +873,9 @@ int hidinput_connect(struct hid_device * + return -1; + } + +- for (k = HID_INPUT_REPORT; k <= HID_FEATURE_REPORT; k++) { ++ report_features(hid); ++ ++ for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { + if (k == HID_OUTPUT_REPORT && + hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) + continue; +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -122,7 +122,7 @@ struct mt_class mt_classes[] = { + { } + }; + +-static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi, ++static void mt_feature_mapping(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage) + { + if (usage->hid == HID_DG_INPUTMODE) { +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -638,7 +638,7 @@ struct hid_driver { + struct hid_input *hidinput, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max); + void (*feature_mapping)(struct hid_device *hdev, +- struct hid_input *hidinput, struct hid_field *field, ++ struct hid_field *field, + struct hid_usage *usage); + #ifdef CONFIG_PM + int (*suspend)(struct hid_device *hdev, pm_message_t message); +From 9804c9eaeacfe78651052c5ddff31099f60ef78c Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Mon, 7 Feb 2011 19:28:01 +0100 +Subject: [PARISC] fix per-cpu flag problem in the cpu affinity checkers + +From: Thomas Gleixner + +commit 9804c9eaeacfe78651052c5ddff31099f60ef78c upstream. + +The CHECK_IRQ_PER_CPU is wrong, it should be checking +irq_to_desc(irq)->status not just irq. + +Signed-off-by: Thomas Gleixner +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/irq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -108,7 +108,7 @@ int cpu_check_affinity(unsigned int irq, + int cpu_dest; + + /* timer and ipi have to always be received on all CPUs */ +- if (CHECK_IRQ_PER_CPU(irq)) { ++ if (CHECK_IRQ_PER_CPU(irq_to_desc(irq)->status)) { + /* Bad linux design decision. The mask has already + * been set; we must reset it */ + cpumask_setall(irq_desc[irq].affinity); +From 47340bd9fefb571888836da942b5aee0e85e959c Mon Sep 17 00:00:00 2001 +From: Andy Botting +Date: Sat, 12 Mar 2011 20:27:22 -0800 +Subject: Input: bcm5974 - add support for MacBookPro8 + +From: Andy Botting + +commit 47340bd9fefb571888836da942b5aee0e85e959c upstream. + +This patch add multitouch support for the MacBookPro8,1 and +MacBookPro8,2 models. + +Signed-off-by: Andy Botting +Signed-off-by: Henrik Rydberg +Acked-by: Jiri Kosina +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-apple.c | 6 ++++++ + drivers/hid/hid-core.c | 6 ++++++ + drivers/hid/hid-ids.h | 3 +++ + drivers/input/mouse/bcm5974.c | 20 ++++++++++++++++++++ + 4 files changed, 35 insertions(+) + +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -481,6 +481,12 @@ static const struct hid_device_id apple_ + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI), ++ .driver_data = APPLE_HAS_FN }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO), ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), ++ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1300,6 +1300,9 @@ static const struct hid_device_id hid_ha + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -1800,6 +1803,9 @@ static const struct hid_device_id hid_mo + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -103,6 +103,9 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 + #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 + #define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a + #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b +--- a/drivers/input/mouse/bcm5974.c ++++ b/drivers/input/mouse/bcm5974.c +@@ -63,6 +63,10 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 + #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 + #define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 ++/* Macbook8 (unibody, March 2011) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -96,6 +100,10 @@ static const struct usb_device_id bcm597 + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), ++ /* MacbookPro8 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI), ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ISO), ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), + /* Terminating entry */ + {} + }; +@@ -274,6 +282,18 @@ static const struct bcm5974_config bcm59 + { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, + { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, ++ USB_DEVICE_ID_APPLE_WELLSPRING5_ISO, ++ USB_DEVICE_ID_APPLE_WELLSPRING5_JIS, ++ HAS_INTEGRATED_BUTTON, ++ 0x84, sizeof(struct bt_data), ++ 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, ++ { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, ++ { DIM_X, DIM_X / SN_COORD, -4415, 5050 }, ++ { DIM_Y, DIM_Y / SN_COORD, -55, 6680 } ++ }, + {} + }; + +From 6ced9e6b3901af4ab6ac0a11231402c888286ea6 Mon Sep 17 00:00:00 2001 +From: Roman Fietze +Date: Sun, 20 Mar 2011 14:50:52 +0100 +Subject: i2c: Fix typo in instantiating-devices document + +From: Roman Fietze + +commit 6ced9e6b3901af4ab6ac0a11231402c888286ea6 upstream. + +The struct i2c_board_info member holding the name is "type", not +"name". + +Signed-off-by: Roman Fietze +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/i2c/instantiating-devices | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Documentation/i2c/instantiating-devices ++++ b/Documentation/i2c/instantiating-devices +@@ -100,7 +100,7 @@ static int __devinit usb_hcd_pnx4008_pro + (...) + i2c_adap = i2c_get_adapter(2); + memset(&i2c_info, 0, sizeof(struct i2c_board_info)); +- strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); ++ strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); + isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, + normal_i2c, NULL); + i2c_put_adapter(i2c_adap); +From 5fd11c0754fa069b6aba64b65734aa2fb193552d Mon Sep 17 00:00:00 2001 +From: Manoj Iyer +Date: Fri, 11 Feb 2011 16:25:31 -0600 +Subject: mmc: sdhci: Add Ricoh e823 PCI ID + +From: Manoj Iyer + +commit 5fd11c0754fa069b6aba64b65734aa2fb193552d upstream. + +Signed-off-by: Manoj Iyer +Signed-off-by: Chris Ball +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-pci.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/mmc/host/sdhci-pci.c ++++ b/drivers/mmc/host/sdhci-pci.c +@@ -547,6 +547,14 @@ static const struct pci_device_id pci_id + }, + + { ++ .vendor = PCI_VENDOR_ID_RICOH, ++ .device = 0xe823, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc, ++ }, ++ ++ { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD, + .subvendor = PCI_ANY_ID, +From 0aab3995485b8a994bf29a995a008c9ea4a28054 Mon Sep 17 00:00:00 2001 +From: Stefan Nilsson XK +Date: Tue, 1 Mar 2011 14:41:04 +0100 +Subject: mmc: sdio: remember new card RCA when redetecting card + +From: Stefan Nilsson XK + +commit 0aab3995485b8a994bf29a995a008c9ea4a28054 upstream. + +During redetection of a SDIO card, a request for a new card RCA +was submitted to the card, but was then overwritten by the old RCA. +This caused the card to be deselected instead of selected when using +the incorrect RCA. This bug's been present since the "oldcard" +handling was introduced in 2.6.32. + +Signed-off-by: Stefan Nilsson XK +Reviewed-by: Ulf Hansson +Reviewed-by: Pawel Wieczorkiewicz +Signed-off-by: Linus Walleij +Signed-off-by: Chris Ball +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/core/sdio.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/mmc/core/sdio.c ++++ b/drivers/mmc/core/sdio.c +@@ -395,6 +395,14 @@ static int mmc_sdio_init_card(struct mmc + if (err) + goto remove; + ++ /* ++ * Update oldcard with the new RCA received from the SDIO ++ * device -- we're doing this so that it's updated in the ++ * "card" struct when oldcard overwrites that later. ++ */ ++ if (oldcard) ++ oldcard->rca = card->rca; ++ + mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); + } + +From 371c394af27ab7d1e58a66bc19d9f1f3ac1f67b4 Mon Sep 17 00:00:00 2001 +From: Alexander van Heukelum +Date: Fri, 11 Mar 2011 21:59:38 +0100 +Subject: x86, binutils, xen: Fix another wrong size directive + +From: Alexander van Heukelum + +commit 371c394af27ab7d1e58a66bc19d9f1f3ac1f67b4 upstream. + +The latest binutils (2.21.0.20110302/Ubuntu) breaks the build +yet another time, under CONFIG_XEN=y due to a .size directive that +refers to a slightly differently named (hence, to the now very +strict and unforgiving assembler, non-existent) symbol. + +[ mingo: + + This unnecessary build breakage caused by new binutils + version 2.21 gets escallated back several kernel releases spanning + several years of Linux history, affecting over 130,000 upstream + kernel commits (!), on CONFIG_XEN=y 64-bit kernels (i.e. essentially + affecting all major Linux distro kernel configs). + + Git annotate tells us that this slight debug symbol code mismatch + bug has been introduced in 2008 in commit 3d75e1b8: + + 3d75e1b8 (Jeremy Fitzhardinge 2008-07-08 15:06:49 -0700 1231) ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) + + The 'bug' is just a slight assymetry in ENTRY()/END() + debug-symbols sequences, with lots of assembly code between the + ENTRY() and the END(): + + ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) + ... + END(do_hypervisor_callback) + + Human reviewers almost never catch such small mismatches, and binutils + never even warned about it either. + + This new binutils version thus breaks the Xen build on all upstream kernels + since v2.6.27, out of the blue. + + This makes a straightforward Git bisection of all 64-bit Xen-enabled kernels + impossible on such binutils, for a bisection window of over hundred + thousand historic commits. (!) + + This is a major fail on the side of binutils and binutils needs to turn + this show-stopper build failure into a warning ASAP. ] + +Signed-off-by: Alexander van Heukelum +Cc: Jeremy Fitzhardinge +Cc: Jan Beulich +Cc: H.J. Lu +Cc: Linus Torvalds +Cc: Andrew Morton +Cc: "H. Peter Anvin" +Cc: Kees Cook +LKML-Reference: <1299877178-26063-1-git-send-email-heukelum@fastmail.fm> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/entry_64.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/entry_64.S ++++ b/arch/x86/kernel/entry_64.S +@@ -1248,7 +1248,7 @@ ENTRY(xen_do_hypervisor_callback) # do + decl PER_CPU_VAR(irq_count) + jmp error_exit + CFI_ENDPROC +-END(do_hypervisor_callback) ++END(xen_do_hypervisor_callback) + + /* + * Hypervisor uses this for application faults while it executes. +From 60d97a840175d3becb2e6de36537a5cdfc0ec3a9 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Sun, 13 Mar 2011 20:06:59 +0000 +Subject: davinci: DM644x EVM: register MUSB device earlier + +From: Sergei Shtylyov + +commit 60d97a840175d3becb2e6de36537a5cdfc0ec3a9 upstream. + +The MUSB driver doesn't see its platform device on DM644x EVM board anymore +since commit 73b089b052a69020b953312a624a6e1eb5b81fab (usb: musb: split davinci +to its own platform_driver) because the new probe is called as subsys_initcall() +now, and the device is registered later than that by the board code. Move the +registration to davinci_evm_init() -- it's safe to do so because the MUSB core +device still gets initialized as fs_initcall() -- which is late enough for the +I2C GPIO expander (which controls VBUS) to be initialized. + +Signed-off-by: Sergei Shtylyov +Acked-by: Felipe Balbi +Tested-by: Sekhar Nori +Signed-off-by: Kevin Hilman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mach-davinci/board-dm644x-evm.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/arch/arm/mach-davinci/board-dm644x-evm.c ++++ b/arch/arm/mach-davinci/board-dm644x-evm.c +@@ -440,11 +440,6 @@ evm_u35_setup(struct i2c_client *client, + gpio_request(gpio + 7, "nCF_SEL"); + gpio_direction_output(gpio + 7, 1); + +- /* irlml6401 switches over 1A, in under 8 msec; +- * now it can be managed by nDRV_VBUS ... +- */ +- davinci_setup_usb(1000, 8); +- + return 0; + } + +@@ -705,6 +700,9 @@ static __init void davinci_evm_init(void + davinci_serial_init(&uart_config); + dm644x_init_asp(&dm644x_evm_snd_data); + ++ /* irlml6401 switches over 1A, in under 8 msec */ ++ davinci_setup_usb(1000, 8); ++ + soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID; + /* Register the fixup for PHY on DaVinci */ + phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, +From ccd32e735de7a941906e093f8dca924bb05c5794 Mon Sep 17 00:00:00 2001 +From: Vivien Didelot +Date: Mon, 21 Mar 2011 17:59:35 +0100 +Subject: hwmon: (sht15) Fix integer overflow in humidity calculation + +From: Vivien Didelot + +commit ccd32e735de7a941906e093f8dca924bb05c5794 upstream. + +An integer overflow occurs in the calculation of RHlinear when the +relative humidity is greater than around 30%. The consequence is a subtle +(but noticeable) error in the resulting humidity measurement. + +Signed-off-by: Vivien Didelot +Signed-off-by: Jean Delvare +Cc: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/sht15.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/hwmon/sht15.c ++++ b/drivers/hwmon/sht15.c +@@ -333,11 +333,11 @@ static inline int sht15_calc_humid(struc + + const int c1 = -4; + const int c2 = 40500; /* x 10 ^ -6 */ +- const int c3 = -2800; /* x10 ^ -9 */ ++ const int c3 = -28; /* x 10 ^ -7 */ + + RHlinear = c1*1000 + + c2 * data->val_humid/1000 +- + (data->val_humid * data->val_humid * c3)/1000000; ++ + (data->val_humid * data->val_humid * c3) / 10000; + return (temp - 25000) * (10000 + 80 * data->val_humid) + / 1000000 + RHlinear; + } -- cgit v1.2.3