From: Greg Kroah-Hartman Date: Fri, 21 Sep 2012 17:55:53 +0000 (-0700) Subject: 3.5-stable patches X-Git-Tag: v3.0.44~81 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4f10b7d39bf8f9c6cafadb0e8f8d76e693277917;p=thirdparty%2Fkernel%2Fstable-queue.git 3.5-stable patches added patches: acpi-pm-fix-resource_lock-dead-lock-in-acpi_power_on_device.patch acpi-pm-infer-parent-power-state-from-child-if-unknown-v2.patch acpi-pm-use-kern_debug-when-no-power-resources-are-found.patch ahci-add-alternate-identifier-for-the-88se9172.patch digsig-add-hash-size-comparision-on-signature-verification.patch dyndbg-fix-for-soh-in-logging-messages.patch fs-proc-fix-potential-unregister_sysctl_table-hang.patch kobject-fix-oops-with-input0-bad-kobj_uevent_env-content-in-show_uevent.patch mmc-atmel-mci-not-busy-flag-has-also-to-be-used-for-read-operations.patch mmc-card-skip-secure-erase-on-movinand-causes-unrecoverable-corruption.patch mmc-mxs-mmc-fix-deadlock-caused-by-recursion-loop.patch mmc-mxs-mmc-fix-deadlock-in-sdio-irq-case.patch mmc-sdhci-esdhc-break-out-early-if-clock-is-0.patch oprofile-s390-fix-uninitialized-memory-access-when-writing-to-oprofilefs.patch perf_event-switch-to-internal-refcount-fix-race-with-close.patch redefine-atomic_init-and-atomic64_init-to-drop-the-casts.patch sound-tegra_alc5632-remove-hp-detect-gpio-inversion.patch sunrpc-fix-a-udp-transport-regression.patch usb-chipidea-udc-add-pullup-fuction-needed-by-the-uvc-gadget.patch usb-gadget-at91udc-don-t-check-for-ep-ep.desc.patch usb-gadget-at91udc-don-t-overwrite-driver-data.patch usb-gadget-dummy_hcd-add-support-for-usb_dt_bos-on-rh.patch usb-gadget-dummy_hcd-fixup-error-probe-path.patch --- diff --git a/queue-3.5/acpi-pm-fix-resource_lock-dead-lock-in-acpi_power_on_device.patch b/queue-3.5/acpi-pm-fix-resource_lock-dead-lock-in-acpi_power_on_device.patch new file mode 100644 index 00000000000..382b7115676 --- /dev/null +++ b/queue-3.5/acpi-pm-fix-resource_lock-dead-lock-in-acpi_power_on_device.patch @@ -0,0 +1,139 @@ +From 40bf66ec9791f1452b90b82aadc3b6e6aee201f5 Mon Sep 17 00:00:00 2001 +From: Lin Ming +Date: Fri, 14 Sep 2012 00:26:33 +0200 +Subject: ACPI / PM: Fix resource_lock dead lock in acpi_power_on_device + +From: Lin Ming + +commit 40bf66ec9791f1452b90b82aadc3b6e6aee201f5 upstream. + +Commit 0090def("ACPI: Add interface to register/unregister device +to/from power resources") used resource_lock to protect the devices list +that relies on power resource. It caused a mutex dead lock, as below + + acpi_power_on ---> lock resource_lock + __acpi_power_on + acpi_power_on_device + acpi_power_get_inferred_state + acpi_power_get_list_state ---> lock resource_lock + +This patch adds a new mutex "devices_lock" to protect the devices list +and calls acpi_power_on_device in acpi_power_on, instead of +__acpi_power_on, after the resource_lock is released. + +[rjw: Changed data type of a boolean variable to bool.] + +Signed-off-by: Lin Ming +Signed-off-by: Aaron Lu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/power.c | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -103,6 +103,7 @@ struct acpi_power_resource { + + /* List of devices relying on this power resource */ + struct acpi_power_resource_device *devices; ++ struct mutex devices_lock; + }; + + static struct list_head acpi_power_resource_list; +@@ -221,7 +222,6 @@ static void acpi_power_on_device(struct + + static int __acpi_power_on(struct acpi_power_resource *resource) + { +- struct acpi_power_resource_device *device_list = resource->devices; + acpi_status status = AE_OK; + + status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); +@@ -234,19 +234,15 @@ static int __acpi_power_on(struct acpi_p + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", + resource->name)); + +- while (device_list) { +- acpi_power_on_device(device_list->device); +- +- device_list = device_list->next; +- } +- + return 0; + } + + static int acpi_power_on(acpi_handle handle) + { + int result = 0; ++ bool resume_device = false; + struct acpi_power_resource *resource = NULL; ++ struct acpi_power_resource_device *device_list; + + result = acpi_power_get_context(handle, &resource); + if (result) +@@ -262,10 +258,25 @@ static int acpi_power_on(acpi_handle han + result = __acpi_power_on(resource); + if (result) + resource->ref_count--; ++ else ++ resume_device = true; + } + + mutex_unlock(&resource->resource_lock); + ++ if (!resume_device) ++ return result; ++ ++ mutex_lock(&resource->devices_lock); ++ ++ device_list = resource->devices; ++ while (device_list) { ++ acpi_power_on_device(device_list->device); ++ device_list = device_list->next; ++ } ++ ++ mutex_unlock(&resource->devices_lock); ++ + return result; + } + +@@ -351,7 +362,7 @@ static void __acpi_power_resource_unregi + if (acpi_power_get_context(res_handle, &resource)) + return; + +- mutex_lock(&resource->resource_lock); ++ mutex_lock(&resource->devices_lock); + prev = NULL; + curr = resource->devices; + while (curr) { +@@ -368,7 +379,7 @@ static void __acpi_power_resource_unregi + prev = curr; + curr = curr->next; + } +- mutex_unlock(&resource->resource_lock); ++ mutex_unlock(&resource->devices_lock); + } + + /* Unlink dev from all power resources in _PR0 */ +@@ -409,10 +420,10 @@ static int __acpi_power_resource_registe + + power_resource_device->device = powered_device; + +- mutex_lock(&resource->resource_lock); ++ mutex_lock(&resource->devices_lock); + power_resource_device->next = resource->devices; + resource->devices = power_resource_device; +- mutex_unlock(&resource->resource_lock); ++ mutex_unlock(&resource->devices_lock); + + return 0; + } +@@ -715,6 +726,7 @@ static int acpi_power_add(struct acpi_de + + resource->device = device; + mutex_init(&resource->resource_lock); ++ mutex_init(&resource->devices_lock); + strcpy(resource->name, device->pnp.bus_id); + strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); + strcpy(acpi_device_class(device), ACPI_POWER_CLASS); diff --git a/queue-3.5/acpi-pm-infer-parent-power-state-from-child-if-unknown-v2.patch b/queue-3.5/acpi-pm-infer-parent-power-state-from-child-if-unknown-v2.patch new file mode 100644 index 00000000000..1c3e0b1f555 --- /dev/null +++ b/queue-3.5/acpi-pm-infer-parent-power-state-from-child-if-unknown-v2.patch @@ -0,0 +1,54 @@ +From 8f7412a792bc989d1bddd3c802282eec09456d57 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Fri, 14 Sep 2012 00:26:24 +0200 +Subject: ACPI / PM: Infer parent power state from child if unknown, v2 + +From: "Rafael J. Wysocki" + +commit 8f7412a792bc989d1bddd3c802282eec09456d57 upstream. + +It turns out that there are ACPI BIOSes defining device objects with +_PSx and without either _PSC or _PRx. For devices corresponding to +those ACPI objetcs __acpi_bus_get_power() returns ACPI_STATE_UNKNOWN +and their initial power states are regarded as unknown as a result. +If such a device is a parent of another power-manageable device, the +child cannot be put into a low-power state through ACPI, because +__acpi_bus_set_power() refuses to change power states of devices +whose parents' power states are unknown. + +To work around this problem, observe that the ACPI power state of +a device cannot be higher-power (lower-number) than the power state +of its parent. Thus, if the device's _PSC method or the +configuration of its power resources indicates that the device is +in D0, the device's parent has to be in D0 as well. Consequently, +if the parent's power state is unknown when we've just learned that +its child's power state is D0, we can safely set the parent's +power.state field to ACPI_STATE_D0. + +Tested-by: Aaron Lu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/bus.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct a + } else if (result == ACPI_STATE_D3_HOT) { + result = ACPI_STATE_D3; + } ++ ++ /* ++ * If we were unsure about the device parent's power state up to this ++ * point, the fact that the device is in D0 implies that the parent has ++ * to be in D0 too. ++ */ ++ if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN ++ && result == ACPI_STATE_D0) ++ device->parent->power.state = ACPI_STATE_D0; ++ + *state = result; + + out: diff --git a/queue-3.5/acpi-pm-use-kern_debug-when-no-power-resources-are-found.patch b/queue-3.5/acpi-pm-use-kern_debug-when-no-power-resources-are-found.patch new file mode 100644 index 00000000000..e22af58d354 --- /dev/null +++ b/queue-3.5/acpi-pm-use-kern_debug-when-no-power-resources-are-found.patch @@ -0,0 +1,37 @@ +From f25b70613c048ceb1df052576fda03321ebf41cf Mon Sep 17 00:00:00 2001 +From: Aaron Lu +Date: Fri, 14 Sep 2012 20:54:44 +0200 +Subject: ACPI / PM: Use KERN_DEBUG when no power resources are found + +From: Aaron Lu + +commit f25b70613c048ceb1df052576fda03321ebf41cf upstream. + +commit a606dac368eed5696fb38e16b1394f1d049c09e9 adds support to link +devices which have _PRx, if a device does not have _PRx, a warning +message will be printed. + +This commit is for ZPODD on Intel ZPODD capable platforms, on other +platforms, it has no problem if there is no power resource for this +device, so a warning here is not appropriate, change it to debug. + +Reported-by: Borislav Petkov +Signed-off-by: Aaron Lu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/power.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -468,7 +468,7 @@ int acpi_power_resource_register_device( + return ret; + + no_power_resource: +- printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); ++ printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!"); + return -ENODEV; + } + diff --git a/queue-3.5/ahci-add-alternate-identifier-for-the-88se9172.patch b/queue-3.5/ahci-add-alternate-identifier-for-the-88se9172.patch new file mode 100644 index 00000000000..dae256f94d9 --- /dev/null +++ b/queue-3.5/ahci-add-alternate-identifier-for-the-88se9172.patch @@ -0,0 +1,32 @@ +From 17c60c6b763cb5b83b0185e7d38d01d18e55a05a Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Tue, 4 Sep 2012 16:07:18 +0100 +Subject: ahci: Add alternate identifier for the 88SE9172 + +From: Alan Cox + +commit 17c60c6b763cb5b83b0185e7d38d01d18e55a05a upstream. + +This can also appear as 0x9192. Reported in bugzilla and confirmed with the +board documentation for these boards. + +Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=42970 +Signed-off-by: Alan Cox +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 +@@ -396,6 +396,8 @@ static const struct pci_device_id ahci_p + .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ + { PCI_DEVICE(0x1b4b, 0x917a), + .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ ++ { PCI_DEVICE(0x1b4b, 0x9192), ++ .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ + { PCI_DEVICE(0x1b4b, 0x91a3), + .driver_data = board_ahci_yes_fbs }, + diff --git a/queue-3.5/digsig-add-hash-size-comparision-on-signature-verification.patch b/queue-3.5/digsig-add-hash-size-comparision-on-signature-verification.patch new file mode 100644 index 00000000000..8d78ec1a83f --- /dev/null +++ b/queue-3.5/digsig-add-hash-size-comparision-on-signature-verification.patch @@ -0,0 +1,40 @@ +From bc01637a80f5b670bd70a0279d3f93fa8de1c96d Mon Sep 17 00:00:00 2001 +From: Dmitry Kasatkin +Date: Wed, 12 Sep 2012 13:26:55 +0300 +Subject: digsig: add hash size comparision on signature verification + +From: Dmitry Kasatkin + +commit bc01637a80f5b670bd70a0279d3f93fa8de1c96d upstream. + +When pkcs_1_v1_5_decode_emsa() returns without error and hash sizes do +not match, hash comparision is not done and digsig_verify_rsa() returns +no error. This is a bug and this patch fixes it. + +The bug was introduced in v3.3 by commit b35e286a640f ("lib/digsig: +pkcs_1_v1_5_decode_emsa cleanup"). + +Signed-off-by: Dmitry Kasatkin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + lib/digsig.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/lib/digsig.c ++++ b/lib/digsig.c +@@ -163,9 +163,11 @@ static int digsig_verify_rsa(struct key + memcpy(out1 + head, p, l); + + err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); ++ if (err) ++ goto err; + +- if (!err && len == hlen) +- err = memcmp(out2, h, hlen); ++ if (len != hlen || memcmp(out2, h, hlen)) ++ err = -EINVAL; + + err: + mpi_free(in); diff --git a/queue-3.5/dyndbg-fix-for-soh-in-logging-messages.patch b/queue-3.5/dyndbg-fix-for-soh-in-logging-messages.patch new file mode 100644 index 00000000000..d59069c0e78 --- /dev/null +++ b/queue-3.5/dyndbg-fix-for-soh-in-logging-messages.patch @@ -0,0 +1,38 @@ +From ebdc82899ec5ed35af1c79ed6a4eeda69dad9b90 Mon Sep 17 00:00:00 2001 +From: Markus Trippelsdorf +Date: Sat, 18 Aug 2012 18:35:51 -0600 +Subject: dyndbg: fix for SOH in logging messages + +From: Markus Trippelsdorf + +commit ebdc82899ec5ed35af1c79ed6a4eeda69dad9b90 upstream. + +commit af7f2158fde was done against master, and clashed with structured +logging's change of KERN_LEVEL to SOH. + +Bisected and fixed by Markus Trippelsdorf. + +Reported-by: Markus Trippelsdorf +Signed-off-by: Jim Cromie +Cc: Linus Torvalds +Cc: Andrew Morton +Cc: Jason Baron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -1895,8 +1895,8 @@ int __dev_printk(const char *level, cons + "DEVICE=+%s:%s", subsys, dev_name(dev)); + } + skip: +- if (level[3]) +- level_extra = &level[3]; /* skip past "" */ ++ if (level[2]) ++ level_extra = &level[2]; /* skip past KERN_SOH "L" */ + + return printk_emit(0, level[1] - '0', + dictlen ? dict : NULL, dictlen, diff --git a/queue-3.5/fs-proc-fix-potential-unregister_sysctl_table-hang.patch b/queue-3.5/fs-proc-fix-potential-unregister_sysctl_table-hang.patch new file mode 100644 index 00000000000..dd6f1f5e161 --- /dev/null +++ b/queue-3.5/fs-proc-fix-potential-unregister_sysctl_table-hang.patch @@ -0,0 +1,55 @@ +From 6bf6104573482570f7103d3e5ddf9574db43a363 Mon Sep 17 00:00:00 2001 +From: Francesco Ruggeri +Date: Thu, 13 Sep 2012 15:03:37 -0700 +Subject: fs/proc: fix potential unregister_sysctl_table hang + +From: Francesco Ruggeri + +commit 6bf6104573482570f7103d3e5ddf9574db43a363 upstream. + +The unregister_sysctl_table() function hangs if all references to its +ctl_table_header structure are not dropped. + +This can happen sometimes because of a leak in proc_sys_lookup(): +proc_sys_lookup() gets a reference to the table via lookup_entry(), but +it does not release it when a subsequent call to sysctl_follow_link() +fails. + +This patch fixes this leak by making sure the reference is always +dropped on return. + +See also commit 076c3eed2c31 ("sysctl: Rewrite proc_sys_lookup +introducing find_entry and lookup_entry") which reorganized this code in +3.4. + +Tested in Linux 3.4.4. + +Signed-off-by: Francesco Ruggeri +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/proc/proc_sysctl.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/proc/proc_sysctl.c ++++ b/fs/proc/proc_sysctl.c +@@ -462,9 +462,6 @@ static struct dentry *proc_sys_lookup(st + + err = ERR_PTR(-ENOMEM); + inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p); +- if (h) +- sysctl_head_finish(h); +- + if (!inode) + goto out; + +@@ -473,6 +470,8 @@ static struct dentry *proc_sys_lookup(st + d_add(dentry, inode); + + out: ++ if (h) ++ sysctl_head_finish(h); + sysctl_head_finish(head); + return err; + } diff --git a/queue-3.5/kobject-fix-oops-with-input0-bad-kobj_uevent_env-content-in-show_uevent.patch b/queue-3.5/kobject-fix-oops-with-input0-bad-kobj_uevent_env-content-in-show_uevent.patch new file mode 100644 index 00000000000..c8dc5113c5a --- /dev/null +++ b/queue-3.5/kobject-fix-oops-with-input0-bad-kobj_uevent_env-content-in-show_uevent.patch @@ -0,0 +1,75 @@ +From 60e233a56609fd963c59e99bd75c663d63fa91b6 Mon Sep 17 00:00:00 2001 +From: Bjørn Mork +Date: Sun, 2 Sep 2012 15:41:34 +0200 +Subject: kobject: fix oops with "input0: bad kobj_uevent_env content in show_uevent()" + +From: Bjørn Mork + +commit 60e233a56609fd963c59e99bd75c663d63fa91b6 upstream. + +Fengguang Wu writes: + +> After the __devinit* removal series, I can still get kernel panic in +> show_uevent(). So there are more sources of bug.. +> +> Debug patch: +> +> @@ -343,8 +343,11 @@ static ssize_t show_uevent(struct device +> goto out; +> +> /* copy keys to file */ +> - for (i = 0; i < env->envp_idx; i++) +> + dev_err(dev, "uevent %d env[%d]: %s/.../%s\n", env->buflen, env->envp_idx, top_kobj->name, dev->kobj.name); +> + for (i = 0; i < env->envp_idx; i++) { +> + printk(KERN_ERR "uevent %d env[%d]: %s\n", (int)count, i, env->envp[i]); +> count += sprintf(&buf[count], "%s\n", env->envp[i]); +> + } +> +> Oops message, the env[] is again not properly initilized: +> +> [ 44.068623] input input0: uevent 61 env[805306368]: input0/.../input0 +> [ 44.069552] uevent 0 env[0]: (null) + +This is a completely different CONFIG_HOTPLUG problem, only +demonstrating another reason why CONFIG_HOTPLUG should go away. I had a +hard time trying to disable it anyway ;-) + +The problem this time is lots of code assuming that a call to +add_uevent_var() will guarantee that env->buflen > 0. This is not true +if CONFIG_HOTPLUG is unset. So things like this end up overwriting +env->envp_idx because the array index is -1: + + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + len = input_print_modalias(&env->buf[env->buflen - 1], + sizeof(env->buf) - env->buflen, + dev, 0); + +Don't know what the best action is, given that there seem to be a *lot* +of this around the kernel. This patch "fixes" the problem for me, but I +don't know if it can be considered an appropriate fix. + +[ It is the correct fix for now, for 3.7 forcing CONFIG_HOTPLUG to +always be on is the longterm fix, but it's too late for 3.6 and older +kernels to resolve this that way - gregkh ] + +Reported-by: Fengguang Wu +Signed-off-by: Bjørn Mork +Tested-by: Fengguang Wu +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/kobject.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/kobject.h ++++ b/include/linux/kobject.h +@@ -224,7 +224,7 @@ static inline int kobject_uevent_env(str + + static inline __printf(2, 3) + int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) +-{ return 0; } ++{ return -ENOMEM; } + + static inline int kobject_action_type(const char *buf, size_t count, + enum kobject_action *type) diff --git a/queue-3.5/mmc-atmel-mci-not-busy-flag-has-also-to-be-used-for-read-operations.patch b/queue-3.5/mmc-atmel-mci-not-busy-flag-has-also-to-be-used-for-read-operations.patch new file mode 100644 index 00000000000..6ad092a06b6 --- /dev/null +++ b/queue-3.5/mmc-atmel-mci-not-busy-flag-has-also-to-be-used-for-read-operations.patch @@ -0,0 +1,60 @@ +From 077d40731edc90ee9dedf63249034c8cd5f694ce Mon Sep 17 00:00:00 2001 +From: Ludovic Desroches +Date: Tue, 24 Jul 2012 11:42:04 +0200 +Subject: mmc: atmel-mci: not busy flag has also to be used for read operations + +From: Ludovic Desroches + +commit 077d40731edc90ee9dedf63249034c8cd5f694ce upstream. + +Even if the datasheet says that the not busy flag has to be used only +for write operations, it's false except for version lesser than v2xx. + +Not waiting on the not busy flag for read operations can cause the +controller to hang-up during the initialization of some SD cards +with DMA after the first CMD6 -- the next command is sent too early. + +Signed-off-by: Ludovic Desroches +Signed-off-by: Chris Ball +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/atmel-mci.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/atmel-mci.c ++++ b/drivers/mmc/host/atmel-mci.c +@@ -81,6 +81,7 @@ struct atmel_mci_caps { + bool has_bad_data_ordering; + bool need_reset_after_xfer; + bool need_blksz_mul_4; ++ bool need_notbusy_for_read_ops; + }; + + struct atmel_mci_dma { +@@ -1619,7 +1620,8 @@ static void atmci_tasklet_func(unsigned + __func__); + atmci_set_completed(host, EVENT_XFER_COMPLETE); + +- if (host->data->flags & MMC_DATA_WRITE) { ++ if (host->caps.need_notbusy_for_read_ops || ++ (host->data->flags & MMC_DATA_WRITE)) { + atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); + state = STATE_WAITING_NOTBUSY; + } else if (host->mrq->stop) { +@@ -2212,6 +2214,7 @@ static void __init atmci_get_cap(struct + host->caps.has_bad_data_ordering = 1; + host->caps.need_reset_after_xfer = 1; + host->caps.need_blksz_mul_4 = 1; ++ host->caps.need_notbusy_for_read_ops = 0; + + /* keep only major version number */ + switch (version & 0xf00) { +@@ -2232,6 +2235,7 @@ static void __init atmci_get_cap(struct + case 0x200: + host->caps.has_rwproof = 1; + host->caps.need_blksz_mul_4 = 0; ++ host->caps.need_notbusy_for_read_ops = 1; + case 0x100: + host->caps.has_bad_data_ordering = 0; + host->caps.need_reset_after_xfer = 0; diff --git a/queue-3.5/mmc-card-skip-secure-erase-on-movinand-causes-unrecoverable-corruption.patch b/queue-3.5/mmc-card-skip-secure-erase-on-movinand-causes-unrecoverable-corruption.patch new file mode 100644 index 00000000000..1c391ddc420 --- /dev/null +++ b/queue-3.5/mmc-card-skip-secure-erase-on-movinand-causes-unrecoverable-corruption.patch @@ -0,0 +1,93 @@ +From 3550ccdb9d8d350e526b809bf3dd92b550a74fe1 Mon Sep 17 00:00:00 2001 +From: Ian Chen +Date: Wed, 29 Aug 2012 15:05:36 +0900 +Subject: mmc: card: Skip secure erase on MoviNAND; causes unrecoverable corruption. + +From: Ian Chen + +commit 3550ccdb9d8d350e526b809bf3dd92b550a74fe1 upstream. + +For several MoviNAND eMMC parts, there are known issues with secure +erase and secure trim. For these specific MoviNAND devices, we skip +these operations. + +Specifically, there is a bug in the eMMC firmware that causes +unrecoverable corruption when the MMC is erased with MMC_CAP_ERASE +enabled. + +References: + +http://forum.xda-developers.com/showthread.php?t=1644364 +https://plus.google.com/111398485184813224730/posts/21pTYfTsCkB#111398485184813224730/posts/21pTYfTsCkB + +Signed-off-by: Ian Chen +Reviewed-by: Namjae Jeon +Acked-by: Jaehoon Chung +Reviewed-by: Linus Walleij +Signed-off-by: Chris Ball +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/card/block.c | 26 +++++++++++++++++++++++++- + include/linux/mmc/card.h | 1 + + 2 files changed, 26 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -1429,7 +1429,8 @@ static int mmc_blk_issue_rq(struct mmc_q + /* complete ongoing async transfer before issuing discard */ + if (card->host->areq) + mmc_blk_issue_rw_rq(mq, NULL); +- if (req->cmd_flags & REQ_SECURE) ++ if (req->cmd_flags & REQ_SECURE && ++ !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN)) + ret = mmc_blk_issue_secdiscard_rq(mq, req); + else + ret = mmc_blk_issue_discard_rq(mq, req); +@@ -1734,6 +1735,7 @@ force_ro_fail: + #define CID_MANFID_SANDISK 0x2 + #define CID_MANFID_TOSHIBA 0x11 + #define CID_MANFID_MICRON 0x13 ++#define CID_MANFID_SAMSUNG 0x15 + + static const struct mmc_fixup blk_fixups[] = + { +@@ -1770,6 +1772,28 @@ static const struct mmc_fixup blk_fixups + MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, + MMC_QUIRK_LONG_READ_TIME), + ++ /* ++ * On these Samsung MoviNAND parts, performing secure erase or ++ * secure trim can result in unrecoverable corruption due to a ++ * firmware bug. ++ */ ++ MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, ++ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), ++ + END_FIXUP + }; + +--- a/include/linux/mmc/card.h ++++ b/include/linux/mmc/card.h +@@ -238,6 +238,7 @@ struct mmc_card { + #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ + #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ + #define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ ++#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */ + /* byte mode */ + unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ + #define MMC_NO_POWER_NOTIFICATION 0 diff --git a/queue-3.5/mmc-mxs-mmc-fix-deadlock-caused-by-recursion-loop.patch b/queue-3.5/mmc-mxs-mmc-fix-deadlock-caused-by-recursion-loop.patch new file mode 100644 index 00000000000..6275efc3ceb --- /dev/null +++ b/queue-3.5/mmc-mxs-mmc-fix-deadlock-caused-by-recursion-loop.patch @@ -0,0 +1,93 @@ +From fc108d24d3a6da63576a460e122fa1df0cbdea20 Mon Sep 17 00:00:00 2001 +From: Lauri Hintsala +Date: Tue, 17 Jul 2012 17:16:10 +0300 +Subject: mmc: mxs-mmc: fix deadlock caused by recursion loop + +From: Lauri Hintsala + +commit fc108d24d3a6da63576a460e122fa1df0cbdea20 upstream. + +Release the lock before mmc_signal_sdio_irq is called by +mxs_mmc_enable_sdio_irq. + +Backtrace: +[ 65.470000] ============================================= +[ 65.470000] [ INFO: possible recursive locking detected ] +[ 65.470000] 3.5.0-rc5 #2 Not tainted +[ 65.470000] --------------------------------------------- +[ 65.470000] ksdioirqd/mmc0/73 is trying to acquire lock: +[ 65.470000] (&(&host->lock)->rlock#2){-.-...}, at: [] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc] +[ 65.470000] +[ 65.470000] but task is already holding lock: +[ 65.470000] (&(&host->lock)->rlock#2){-.-...}, at: [] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc] +[ 65.470000] +[ 65.470000] other info that might help us debug this: +[ 65.470000] Possible unsafe locking scenario: +[ 65.470000] +[ 65.470000] CPU0 +[ 65.470000] ---- +[ 65.470000] lock(&(&host->lock)->rlock#2); +[ 65.470000] lock(&(&host->lock)->rlock#2); +[ 65.470000] +[ 65.470000] *** DEADLOCK *** +[ 65.470000] +[ 65.470000] May be due to missing lock nesting notation +[ 65.470000] +[ 65.470000] 1 lock held by ksdioirqd/mmc0/73: +[ 65.470000] #0: (&(&host->lock)->rlock#2){-.-...}, at: [] mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc] +[ 65.470000] +[ 65.470000] stack backtrace: +[ 65.470000] [] (unwind_backtrace+0x0/0xf4) from [] (__lock_acquire+0x14f8/0x1b98) +[ 65.470000] [] (__lock_acquire+0x14f8/0x1b98) from [] (lock_acquire+0xa0/0x108) +[ 65.470000] [] (lock_acquire+0xa0/0x108) from [] (_raw_spin_lock_irqsave+0x48/0x5c) +[ 65.470000] [] (_raw_spin_lock_irqsave+0x48/0x5c) from [] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) +[ 65.470000] [] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) from [] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) +[ 65.470000] [] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) from [] (sdio_irq_thread+0x1bc/0x274) +[ 65.470000] [] (sdio_irq_thread+0x1bc/0x274) from [] (kthread+0x8c/0x98) +[ 65.470000] [] (kthread+0x8c/0x98) from [] (kernel_thread_exit+0x0/0x8) +[ 65.470000] BUG: spinlock lockup suspected on CPU#0, ksdioirqd/mmc0/73 +[ 65.470000] lock: 0xc3358724, .magic: dead4ead, .owner: ksdioirqd/mmc0/73, .owner_cpu: 0 +[ 65.470000] [] (unwind_backtrace+0x0/0xf4) from [] (do_raw_spin_lock+0x100/0x144) +[ 65.470000] [] (do_raw_spin_lock+0x100/0x144) from [] (_raw_spin_lock_irqsave+0x50/0x5c) +[ 65.470000] [] (_raw_spin_lock_irqsave+0x50/0x5c) from [] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) +[ 65.470000] [] (mxs_mmc_enable_sdio_irq+0x18/0xdc [mxs_mmc]) from [] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) +[ 65.470000] [] (mxs_mmc_enable_sdio_irq+0xc8/0xdc [mxs_mmc]) from [] (sdio_irq_thread+0x1bc/0x274) +[ 65.470000] [] (sdio_irq_thread+0x1bc/0x274) from [] (kthread+0x8c/0x98) +[ 65.470000] [] (kthread+0x8c/0x98) from [] (kernel_thread_exit+0x0/0x8) + +Reported-by: Attila Kinali +Signed-off-by: Lauri Hintsala +Acked-by: Shawn Guo +Signed-off-by: Chris Ball +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/mxs-mmc.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/mmc/host/mxs-mmc.c ++++ b/drivers/mmc/host/mxs-mmc.c +@@ -637,11 +637,6 @@ static void mxs_mmc_enable_sdio_irq(stru + host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); + writel(BM_SSP_CTRL1_SDIO_IRQ_EN, + host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); +- +- if (readl(host->base + HW_SSP_STATUS(host)) & +- BM_SSP_STATUS_SDIO_IRQ) +- mmc_signal_sdio_irq(host->mmc); +- + } else { + writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, + host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); +@@ -650,6 +645,11 @@ static void mxs_mmc_enable_sdio_irq(stru + } + + spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (enable && readl(host->base + HW_SSP_STATUS(host)) & ++ BM_SSP_STATUS_SDIO_IRQ) ++ mmc_signal_sdio_irq(host->mmc); ++ + } + + static const struct mmc_host_ops mxs_mmc_ops = { diff --git a/queue-3.5/mmc-mxs-mmc-fix-deadlock-in-sdio-irq-case.patch b/queue-3.5/mmc-mxs-mmc-fix-deadlock-in-sdio-irq-case.patch new file mode 100644 index 00000000000..cb1bb62a25b --- /dev/null +++ b/queue-3.5/mmc-mxs-mmc-fix-deadlock-in-sdio-irq-case.patch @@ -0,0 +1,93 @@ +From 1af36b2a993dddfa3d6860ec4879c9e8abc9b976 Mon Sep 17 00:00:00 2001 +From: Lauri Hintsala +Date: Tue, 17 Jul 2012 17:16:09 +0300 +Subject: mmc: mxs-mmc: fix deadlock in SDIO IRQ case + +From: Lauri Hintsala + +commit 1af36b2a993dddfa3d6860ec4879c9e8abc9b976 upstream. + +Release the lock before mmc_signal_sdio_irq is called by mxs_mmc_irq_handler. + +Backtrace: +[ 79.660000] ============================================= +[ 79.660000] [ INFO: possible recursive locking detected ] +[ 79.660000] 3.4.0-00009-g3e96082-dirty #11 Not tainted +[ 79.660000] --------------------------------------------- +[ 79.660000] swapper/0 is trying to acquire lock: +[ 79.660000] (&(&host->lock)->rlock#2){-.....}, at: [] mxs_mmc_enable_sdio_irq+0x18/0xd4 +[ 79.660000] +[ 79.660000] but task is already holding lock: +[ 79.660000] (&(&host->lock)->rlock#2){-.....}, at: [] mxs_mmc_irq_handler+0x1c/0xe8 +[ 79.660000] +[ 79.660000] other info that might help us debug this: +[ 79.660000] Possible unsafe locking scenario: +[ 79.660000] +[ 79.660000] CPU0 +[ 79.660000] ---- +[ 79.660000] lock(&(&host->lock)->rlock#2); +[ 79.660000] lock(&(&host->lock)->rlock#2); +[ 79.660000] +[ 79.660000] *** DEADLOCK *** +[ 79.660000] +[ 79.660000] May be due to missing lock nesting notation +[ 79.660000] +[ 79.660000] 1 lock held by swapper/0: +[ 79.660000] #0: (&(&host->lock)->rlock#2){-.....}, at: [] mxs_mmc_irq_handler+0x1c/0xe8 +[ 79.660000] +[ 79.660000] stack backtrace: +[ 79.660000] [] (unwind_backtrace+0x0/0xf4) from [] (__lock_acquire+0x1948/0x1d48) +[ 79.660000] [] (__lock_acquire+0x1948/0x1d48) from [] (lock_acquire+0xe0/0xf8) +[ 79.660000] [] (lock_acquire+0xe0/0xf8) from [] (_raw_spin_lock_irqsave+0x44/0x58) +[ 79.660000] [] (_raw_spin_lock_irqsave+0x44/0x58) from [] (mxs_mmc_enable_sdio_irq+0x18/0xd4) +[ 79.660000] [] (mxs_mmc_enable_sdio_irq+0x18/0xd4) from [] (mxs_mmc_irq_handler+0xd4/0xe8) +[ 79.660000] [] (mxs_mmc_irq_handler+0xd4/0xe8) from [] (handle_irq_event_percpu+0x70/0x254) +[ 79.660000] [] (handle_irq_event_percpu+0x70/0x254) from [] (handle_irq_event+0x3c/0x5c) +[ 79.660000] [] (handle_irq_event+0x3c/0x5c) from [] (handle_level_irq+0x90/0x110) +[ 79.660000] [] (handle_level_irq+0x90/0x110) from [] (generic_handle_irq+0x38/0x50) +[ 79.660000] [] (generic_handle_irq+0x38/0x50) from [] (handle_IRQ+0x30/0x84) +[ 79.660000] [] (handle_IRQ+0x30/0x84) from [] (__irq_svc+0x38/0x60) +[ 79.660000] [] (__irq_svc+0x38/0x60) from [] (default_idle+0x2c/0x40) +[ 79.660000] [] (default_idle+0x2c/0x40) from [] (cpu_idle+0x64/0xcc) +[ 79.660000] [] (cpu_idle+0x64/0xcc) from [] (start_kernel+0x244/0x2c8) +[ 79.660000] BUG: spinlock lockup on CPU#0, swapper/0 +[ 79.660000] lock: c398cb2c, .magic: dead4ead, .owner: swapper/0, .owner_cpu: 0 +[ 79.660000] [] (unwind_backtrace+0x0/0xf4) from [] (do_raw_spin_lock+0xf0/0x144) +[ 79.660000] [] (do_raw_spin_lock+0xf0/0x144) from [] (_raw_spin_lock_irqsave+0x4c/0x58) +[ 79.660000] [] (_raw_spin_lock_irqsave+0x4c/0x58) from [] (mxs_mmc_enable_sdio_irq+0x18/0xd4) +[ 79.660000] [] (mxs_mmc_enable_sdio_irq+0x18/0xd4) from [] (mxs_mmc_irq_handler+0xd4/0xe8) +[ 79.660000] [] (mxs_mmc_irq_handler+0xd4/0xe8) from [] (handle_irq_event_percpu+0x70/0x254) +[ 79.660000] [] (handle_irq_event_percpu+0x70/0x254) from [] (handle_irq_event+0x3c/0x5c) +[ 79.660000] [] (handle_irq_event+0x3c/0x5c) from [] (handle_level_irq+0x90/0x110) +[ 79.660000] [] (handle_level_irq+0x90/0x110) from [] (generic_handle_irq+0x38/0x50) +[ 79.660000] [] (generic_handle_irq+0x38/0x50) from [] (handle_IRQ+0x30/0x84) +[ 79.660000] [] (handle_IRQ+0x30/0x84) from [] (__irq_svc+0x38/0x60) +[ 79.660000] [] (__irq_svc+0x38/0x60) from [] (default_idle+0x2c/0x40) +[ 79.660000] [] (default_idle+0x2c/0x40) from [] (cpu_idle+0x64/0xcc) +[ 79.660000] [] (cpu_idle+0x64/0xcc) from [] (start_kernel+0x244/0x2c8) + +Signed-off-by: Lauri Hintsala +Acked-by: Shawn Guo +Signed-off-by: Chris Ball +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/mxs-mmc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/mmc/host/mxs-mmc.c ++++ b/drivers/mmc/host/mxs-mmc.c +@@ -278,11 +278,11 @@ static irqreturn_t mxs_mmc_irq_handler(i + writel(stat & MXS_MMC_IRQ_BITS, + host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); + ++ spin_unlock(&host->lock); ++ + if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) + mmc_signal_sdio_irq(host->mmc); + +- spin_unlock(&host->lock); +- + if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ) + cmd->error = -ETIMEDOUT; + else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) diff --git a/queue-3.5/mmc-sdhci-esdhc-break-out-early-if-clock-is-0.patch b/queue-3.5/mmc-sdhci-esdhc-break-out-early-if-clock-is-0.patch new file mode 100644 index 00000000000..aece29821fa --- /dev/null +++ b/queue-3.5/mmc-sdhci-esdhc-break-out-early-if-clock-is-0.patch @@ -0,0 +1,43 @@ +From 74f330bceaa7b88d06062e1cac3d519a3dfc041e Mon Sep 17 00:00:00 2001 +From: Shawn Guo +Date: Wed, 22 Aug 2012 23:10:01 +0800 +Subject: mmc: sdhci-esdhc: break out early if clock is 0 + +From: Shawn Guo + +commit 74f330bceaa7b88d06062e1cac3d519a3dfc041e upstream. + +Since commit 30832ab56 ("mmc: sdhci: Always pass clock request value +zero to set_clock host op") was merged, esdhc_set_clock starts hitting +"if (clock == 0)" where ESDHC_SYSTEM_CONTROL has been operated. This +causes SDHCI card-detection function being broken. Fix the regression +by moving "if (clock == 0)" above ESDHC_SYSTEM_CONTROL operation. + +Signed-off-by: Shawn Guo +Signed-off-by: Chris Ball +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-esdhc.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/host/sdhci-esdhc.h ++++ b/drivers/mmc/host/sdhci-esdhc.h +@@ -48,14 +48,14 @@ static inline void esdhc_set_clock(struc + int div = 1; + u32 temp; + ++ if (clock == 0) ++ goto out; ++ + temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); + temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN + | ESDHC_CLOCK_MASK); + sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); + +- if (clock == 0) +- goto out; +- + while (host->max_clk / pre_div / 16 > clock && pre_div < 256) + pre_div *= 2; + diff --git a/queue-3.5/oprofile-s390-fix-uninitialized-memory-access-when-writing-to-oprofilefs.patch b/queue-3.5/oprofile-s390-fix-uninitialized-memory-access-when-writing-to-oprofilefs.patch new file mode 100644 index 00000000000..07154b31eda --- /dev/null +++ b/queue-3.5/oprofile-s390-fix-uninitialized-memory-access-when-writing-to-oprofilefs.patch @@ -0,0 +1,71 @@ +From 81ff3478d9ba7f0b48b0abef740e542fd83adf79 Mon Sep 17 00:00:00 2001 +From: Robert Richter +Date: Thu, 19 Jul 2012 18:28:26 +0200 +Subject: oprofile, s390: Fix uninitialized memory access when writing to oprofilefs + +From: Robert Richter + +commit 81ff3478d9ba7f0b48b0abef740e542fd83adf79 upstream. + +If oprofilefs_ulong_from_user() is called with count equals zero, *val +remains unchanged. Depending on the implementation it might be +uninitialized. Fixing users of oprofilefs_ulong_ from_user(). + +We missed these s390 changes with: + + 913050b oprofile: Fix uninitialized memory access when writing to writing to oprofilefs + +Signed-off-by: Robert Richter +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/oprofile/init.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/arch/s390/oprofile/init.c ++++ b/arch/s390/oprofile/init.c +@@ -171,7 +171,7 @@ static ssize_t hw_interval_write(struct + if (*offset) + return -EINVAL; + retval = oprofilefs_ulong_from_user(&val, buf, count); +- if (retval) ++ if (retval <= 0) + return retval; + if (val < oprofile_min_interval) + oprofile_hw_interval = oprofile_min_interval; +@@ -214,7 +214,7 @@ static ssize_t hwsampler_zero_write(stru + return -EINVAL; + + retval = oprofilefs_ulong_from_user(&val, buf, count); +- if (retval) ++ if (retval <= 0) + return retval; + if (val != 0) + return -EINVAL; +@@ -245,7 +245,7 @@ static ssize_t hwsampler_kernel_write(st + return -EINVAL; + + retval = oprofilefs_ulong_from_user(&val, buf, count); +- if (retval) ++ if (retval <= 0) + return retval; + + if (val != 0 && val != 1) +@@ -280,7 +280,7 @@ static ssize_t hwsampler_user_write(stru + return -EINVAL; + + retval = oprofilefs_ulong_from_user(&val, buf, count); +- if (retval) ++ if (retval <= 0) + return retval; + + if (val != 0 && val != 1) +@@ -319,7 +319,7 @@ static ssize_t timer_enabled_write(struc + return -EINVAL; + + retval = oprofilefs_ulong_from_user(&val, buf, count); +- if (retval) ++ if (retval <= 0) + return retval; + + if (val != 0 && val != 1) diff --git a/queue-3.5/perf_event-switch-to-internal-refcount-fix-race-with-close.patch b/queue-3.5/perf_event-switch-to-internal-refcount-fix-race-with-close.patch new file mode 100644 index 00000000000..abb6ebad700 --- /dev/null +++ b/queue-3.5/perf_event-switch-to-internal-refcount-fix-race-with-close.patch @@ -0,0 +1,217 @@ +From a6fa941d94b411bbd2b6421ffbde6db3c93e65ab Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 20 Aug 2012 14:59:25 +0100 +Subject: perf_event: Switch to internal refcount, fix race with close() + +From: Al Viro + +commit a6fa941d94b411bbd2b6421ffbde6db3c93e65ab upstream. + +Don't mess with file refcounts (or keep a reference to file, for +that matter) in perf_event. Use explicit refcount of its own +instead. Deal with the race between the final reference to event +going away and new children getting created for it by use of +atomic_long_inc_not_zero() in inherit_event(); just have the +latter free what it had allocated and return NULL, that works +out just fine (children of siblings of something doomed are +created as singletons, same as if the child of leader had been +created and immediately killed). + +Signed-off-by: Al Viro +Signed-off-by: Peter Zijlstra +Link: http://lkml.kernel.org/r/20120820135925.GG23464@ZenIV.linux.org.uk +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/perf_event.h | 2 - + kernel/events/core.c | 62 +++++++++++++++++++++++---------------------- + 2 files changed, 34 insertions(+), 30 deletions(-) + +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -925,7 +925,7 @@ struct perf_event { + struct hw_perf_event hw; + + struct perf_event_context *ctx; +- struct file *filp; ++ atomic_long_t refcount; + + /* + * These accumulate total time (in nanoseconds) that children +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -2933,12 +2933,12 @@ EXPORT_SYMBOL_GPL(perf_event_release_ker + /* + * Called when the last reference to the file is gone. + */ +-static int perf_release(struct inode *inode, struct file *file) ++static void put_event(struct perf_event *event) + { +- struct perf_event *event = file->private_data; + struct task_struct *owner; + +- file->private_data = NULL; ++ if (!atomic_long_dec_and_test(&event->refcount)) ++ return; + + rcu_read_lock(); + owner = ACCESS_ONCE(event->owner); +@@ -2973,7 +2973,13 @@ static int perf_release(struct inode *in + put_task_struct(owner); + } + +- return perf_event_release_kernel(event); ++ perf_event_release_kernel(event); ++} ++ ++static int perf_release(struct inode *inode, struct file *file) ++{ ++ put_event(file->private_data); ++ return 0; + } + + u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) +@@ -3225,7 +3231,7 @@ unlock: + + static const struct file_operations perf_fops; + +-static struct perf_event *perf_fget_light(int fd, int *fput_needed) ++static struct file *perf_fget_light(int fd, int *fput_needed) + { + struct file *file; + +@@ -3239,7 +3245,7 @@ static struct perf_event *perf_fget_ligh + return ERR_PTR(-EBADF); + } + +- return file->private_data; ++ return file; + } + + static int perf_event_set_output(struct perf_event *event, +@@ -3271,19 +3277,21 @@ static long perf_ioctl(struct file *file + + case PERF_EVENT_IOC_SET_OUTPUT: + { ++ struct file *output_file = NULL; + struct perf_event *output_event = NULL; + int fput_needed = 0; + int ret; + + if (arg != -1) { +- output_event = perf_fget_light(arg, &fput_needed); +- if (IS_ERR(output_event)) +- return PTR_ERR(output_event); ++ output_file = perf_fget_light(arg, &fput_needed); ++ if (IS_ERR(output_file)) ++ return PTR_ERR(output_file); ++ output_event = output_file->private_data; + } + + ret = perf_event_set_output(event, output_event); + if (output_event) +- fput_light(output_event->filp, fput_needed); ++ fput_light(output_file, fput_needed); + + return ret; + } +@@ -5922,6 +5930,7 @@ perf_event_alloc(struct perf_event_attr + + mutex_init(&event->mmap_mutex); + ++ atomic_long_set(&event->refcount, 1); + event->cpu = cpu; + event->attr = *attr; + event->group_leader = group_leader; +@@ -6232,12 +6241,12 @@ SYSCALL_DEFINE5(perf_event_open, + return event_fd; + + if (group_fd != -1) { +- group_leader = perf_fget_light(group_fd, &fput_needed); +- if (IS_ERR(group_leader)) { +- err = PTR_ERR(group_leader); ++ group_file = perf_fget_light(group_fd, &fput_needed); ++ if (IS_ERR(group_file)) { ++ err = PTR_ERR(group_file); + goto err_fd; + } +- group_file = group_leader->filp; ++ group_leader = group_file->private_data; + if (flags & PERF_FLAG_FD_OUTPUT) + output_event = group_leader; + if (flags & PERF_FLAG_FD_NO_GROUP) +@@ -6372,7 +6381,6 @@ SYSCALL_DEFINE5(perf_event_open, + put_ctx(gctx); + } + +- event->filp = event_file; + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + +@@ -6462,7 +6470,6 @@ perf_event_create_kernel_counter(struct + goto err_free; + } + +- event->filp = NULL; + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + perf_install_in_context(ctx, event, cpu); +@@ -6511,7 +6518,7 @@ static void sync_child_event(struct perf + * Release the parent event, if this was the last + * reference to it. + */ +- fput(parent_event->filp); ++ put_event(parent_event); + } + + static void +@@ -6587,9 +6594,8 @@ static void perf_event_exit_task_context + * + * __perf_event_exit_task() + * sync_child_event() +- * fput(parent_event->filp) +- * perf_release() +- * mutex_lock(&ctx->mutex) ++ * put_event() ++ * mutex_lock(&ctx->mutex) + * + * But since its the parent context it won't be the same instance. + */ +@@ -6657,7 +6663,7 @@ static void perf_free_event(struct perf_ + list_del_init(&event->child_list); + mutex_unlock(&parent->child_mutex); + +- fput(parent->filp); ++ put_event(parent); + + perf_group_detach(event); + list_del_event(event, ctx); +@@ -6737,6 +6743,12 @@ inherit_event(struct perf_event *parent_ + NULL, NULL); + if (IS_ERR(child_event)) + return child_event; ++ ++ if (!atomic_long_inc_not_zero(&parent_event->refcount)) { ++ free_event(child_event); ++ return NULL; ++ } ++ + get_ctx(child_ctx); + + /* +@@ -6778,14 +6790,6 @@ inherit_event(struct perf_event *parent_ + raw_spin_unlock_irqrestore(&child_ctx->lock, flags); + + /* +- * Get a reference to the parent filp - we will fput it +- * when the child event exits. This is safe to do because +- * we are in the parent and we know that the filp still +- * exists and has a nonzero count: +- */ +- atomic_long_inc(&parent_event->filp->f_count); +- +- /* + * Link this into the parent event's child list + */ + WARN_ON_ONCE(parent_event->ctx->parent_ctx); diff --git a/queue-3.5/redefine-atomic_init-and-atomic64_init-to-drop-the-casts.patch b/queue-3.5/redefine-atomic_init-and-atomic64_init-to-drop-the-casts.patch new file mode 100644 index 00000000000..c8a39ad1b99 --- /dev/null +++ b/queue-3.5/redefine-atomic_init-and-atomic64_init-to-drop-the-casts.patch @@ -0,0 +1,51 @@ +From 67a806d9499353fabd5b5ff07337f3aa88a1c3ba Mon Sep 17 00:00:00 2001 +From: Mel Gorman +Date: Sun, 19 Aug 2012 14:41:03 +1200 +Subject: Redefine ATOMIC_INIT and ATOMIC64_INIT to drop the casts + +From: Mel Gorman + +commit 67a806d9499353fabd5b5ff07337f3aa88a1c3ba upstream. + +The following build error occurred during an alpha build: + + net/core/sock.c:274:36: error: initializer element is not constant + +Dave Anglin says: +> Here is the line in sock.i: +> +> struct static_key memalloc_socks = ((struct static_key) { .enabled = +> ((atomic_t) { (0) }) }); + +The above line contains two compound literals. It also uses a designated +initializer to initialize the field enabled. A compound literal is not a +constant expression. + +The location of the above statement isn't fully clear, but if a compound +literal occurs outside the body of a function, the initializer list must +consist of constant expressions. + +Signed-off-by: Mel Gorman +Signed-off-by: Fengguang Wu +Signed-off-by: Michael Cree +Acked-by: Matt Turner +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/alpha/include/asm/atomic.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/alpha/include/asm/atomic.h ++++ b/arch/alpha/include/asm/atomic.h +@@ -14,8 +14,8 @@ + */ + + +-#define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) +-#define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) ++#define ATOMIC_INIT(i) { (i) } ++#define ATOMIC64_INIT(i) { (i) } + + #define atomic_read(v) (*(volatile int *)&(v)->counter) + #define atomic64_read(v) (*(volatile long *)&(v)->counter) diff --git a/queue-3.5/series b/queue-3.5/series index 7d824f53fe8..44a5a6c106e 100644 --- a/queue-3.5/series +++ b/queue-3.5/series @@ -64,3 +64,26 @@ staging-comedi-amplc_pci224-fix-pci-ref-count.patch staging-comedi-das08-correct-ao-output-for-das08jr-16-ao.patch staging-comedi-das08-correct-ai-encoding-for-das08jr-16-ao.patch usb-option-replace-zte-k5006-z-entry-with-vendor-class-rule.patch +fs-proc-fix-potential-unregister_sysctl_table-hang.patch +sound-tegra_alc5632-remove-hp-detect-gpio-inversion.patch +perf_event-switch-to-internal-refcount-fix-race-with-close.patch +acpi-pm-infer-parent-power-state-from-child-if-unknown-v2.patch +acpi-pm-fix-resource_lock-dead-lock-in-acpi_power_on_device.patch +acpi-pm-use-kern_debug-when-no-power-resources-are-found.patch +mmc-mxs-mmc-fix-deadlock-in-sdio-irq-case.patch +mmc-mxs-mmc-fix-deadlock-caused-by-recursion-loop.patch +mmc-sdhci-esdhc-break-out-early-if-clock-is-0.patch +mmc-atmel-mci-not-busy-flag-has-also-to-be-used-for-read-operations.patch +mmc-card-skip-secure-erase-on-movinand-causes-unrecoverable-corruption.patch +oprofile-s390-fix-uninitialized-memory-access-when-writing-to-oprofilefs.patch +usb-chipidea-udc-add-pullup-fuction-needed-by-the-uvc-gadget.patch +usb-gadget-dummy_hcd-fixup-error-probe-path.patch +usb-gadget-dummy_hcd-add-support-for-usb_dt_bos-on-rh.patch +usb-gadget-at91udc-don-t-overwrite-driver-data.patch +usb-gadget-at91udc-don-t-check-for-ep-ep.desc.patch +ahci-add-alternate-identifier-for-the-88se9172.patch +kobject-fix-oops-with-input0-bad-kobj_uevent_env-content-in-show_uevent.patch +dyndbg-fix-for-soh-in-logging-messages.patch +redefine-atomic_init-and-atomic64_init-to-drop-the-casts.patch +digsig-add-hash-size-comparision-on-signature-verification.patch +sunrpc-fix-a-udp-transport-regression.patch diff --git a/queue-3.5/sound-tegra_alc5632-remove-hp-detect-gpio-inversion.patch b/queue-3.5/sound-tegra_alc5632-remove-hp-detect-gpio-inversion.patch new file mode 100644 index 00000000000..ad83ebca278 --- /dev/null +++ b/queue-3.5/sound-tegra_alc5632-remove-hp-detect-gpio-inversion.patch @@ -0,0 +1,32 @@ +From c921928661eda599d73a6a86e58bdd5aecfa18cb Mon Sep 17 00:00:00 2001 +From: Stephen Warren +Date: Fri, 24 Aug 2012 21:20:15 -0600 +Subject: sound: tegra_alc5632: remove HP detect GPIO inversion + +From: Stephen Warren + +commit c921928661eda599d73a6a86e58bdd5aecfa18cb upstream. + +Both the schematics and practical testing show that the HP detect GPIO +is high when the headphones are plugged in. Hence, the snd_soc_jack_gpio +should not specify to invert the signal. + +Signed-off-by: Stephen Warren +Acked-by: Andrey Danin +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/tegra/tegra_alc5632.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/sound/soc/tegra/tegra_alc5632.c ++++ b/sound/soc/tegra/tegra_alc5632.c +@@ -92,7 +92,6 @@ static struct snd_soc_jack_gpio tegra_al + .name = "Headset detection", + .report = SND_JACK_HEADSET, + .debounce_time = 150, +- .invert = 1, + }; + + static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { diff --git a/queue-3.5/sunrpc-fix-a-udp-transport-regression.patch b/queue-3.5/sunrpc-fix-a-udp-transport-regression.patch new file mode 100644 index 00000000000..e6ba96bf484 --- /dev/null +++ b/queue-3.5/sunrpc-fix-a-udp-transport-regression.patch @@ -0,0 +1,155 @@ +From f39c1bfb5a03e2d255451bff05be0d7255298fa4 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 7 Sep 2012 11:08:50 -0400 +Subject: SUNRPC: Fix a UDP transport regression + +From: Trond Myklebust + +commit f39c1bfb5a03e2d255451bff05be0d7255298fa4 upstream. + +Commit 43cedbf0e8dfb9c5610eb7985d5f21263e313802 (SUNRPC: Ensure that +we grab the XPRT_LOCK before calling xprt_alloc_slot) is causing +hangs in the case of NFS over UDP mounts. + +Since neither the UDP or the RDMA transport mechanism use dynamic slot +allocation, we can skip grabbing the socket lock for those transports. +Add a new rpc_xprt_op to allow switching between the TCP and UDP/RDMA +case. + +Note that the NFSv4.1 back channel assigns the slot directly +through rpc_run_bc_task, so we can ignore that case. + +Reported-by: Dick Streefland +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/sunrpc/xprt.h | 3 +++ + net/sunrpc/xprt.c | 34 ++++++++++++++++++++-------------- + net/sunrpc/xprtrdma/transport.c | 1 + + net/sunrpc/xprtsock.c | 3 +++ + 4 files changed, 27 insertions(+), 14 deletions(-) + +--- a/include/linux/sunrpc/xprt.h ++++ b/include/linux/sunrpc/xprt.h +@@ -114,6 +114,7 @@ struct rpc_xprt_ops { + void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); + int (*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); + void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); ++ void (*alloc_slot)(struct rpc_xprt *xprt, struct rpc_task *task); + void (*rpcbind)(struct rpc_task *task); + void (*set_port)(struct rpc_xprt *xprt, unsigned short port); + void (*connect)(struct rpc_task *task); +@@ -279,6 +280,8 @@ void xprt_connect(struct rpc_task *tas + void xprt_reserve(struct rpc_task *task); + int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task); + int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); ++void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); ++void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); + int xprt_prepare_transmit(struct rpc_task *task); + void xprt_transmit(struct rpc_task *task); + void xprt_end_transmit(struct rpc_task *task); +--- a/net/sunrpc/xprt.c ++++ b/net/sunrpc/xprt.c +@@ -969,11 +969,11 @@ static bool xprt_dynamic_free_slot(struc + return false; + } + +-static void xprt_alloc_slot(struct rpc_task *task) ++void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) + { +- struct rpc_xprt *xprt = task->tk_xprt; + struct rpc_rqst *req; + ++ spin_lock(&xprt->reserve_lock); + if (!list_empty(&xprt->free)) { + req = list_entry(xprt->free.next, struct rpc_rqst, rq_list); + list_del(&req->rq_list); +@@ -994,12 +994,29 @@ static void xprt_alloc_slot(struct rpc_t + default: + task->tk_status = -EAGAIN; + } ++ spin_unlock(&xprt->reserve_lock); + return; + out_init_req: + task->tk_status = 0; + task->tk_rqstp = req; + xprt_request_init(task, xprt); ++ spin_unlock(&xprt->reserve_lock); ++} ++EXPORT_SYMBOL_GPL(xprt_alloc_slot); ++ ++void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) ++{ ++ /* Note: grabbing the xprt_lock_write() ensures that we throttle ++ * new slot allocation if the transport is congested (i.e. when ++ * reconnecting a stream transport or when out of socket write ++ * buffer space). ++ */ ++ if (xprt_lock_write(xprt, task)) { ++ xprt_alloc_slot(xprt, task); ++ xprt_release_write(xprt, task); ++ } + } ++EXPORT_SYMBOL_GPL(xprt_lock_and_alloc_slot); + + static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) + { +@@ -1083,20 +1100,9 @@ void xprt_reserve(struct rpc_task *task) + if (task->tk_rqstp != NULL) + return; + +- /* Note: grabbing the xprt_lock_write() here is not strictly needed, +- * but ensures that we throttle new slot allocation if the transport +- * is congested (e.g. if reconnecting or if we're out of socket +- * write buffer space). +- */ + task->tk_timeout = 0; + task->tk_status = -EAGAIN; +- if (!xprt_lock_write(xprt, task)) +- return; +- +- spin_lock(&xprt->reserve_lock); +- xprt_alloc_slot(task); +- spin_unlock(&xprt->reserve_lock); +- xprt_release_write(xprt, task); ++ xprt->ops->alloc_slot(xprt, task); + } + + static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) +--- a/net/sunrpc/xprtrdma/transport.c ++++ b/net/sunrpc/xprtrdma/transport.c +@@ -713,6 +713,7 @@ static void xprt_rdma_print_stats(struct + static struct rpc_xprt_ops xprt_rdma_procs = { + .reserve_xprt = xprt_rdma_reserve_xprt, + .release_xprt = xprt_release_xprt_cong, /* sunrpc/xprt.c */ ++ .alloc_slot = xprt_alloc_slot, + .release_request = xprt_release_rqst_cong, /* ditto */ + .set_retrans_timeout = xprt_set_retrans_timeout_def, /* ditto */ + .rpcbind = rpcb_getport_async, /* sunrpc/rpcb_clnt.c */ +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -2433,6 +2433,7 @@ static void bc_destroy(struct rpc_xprt * + static struct rpc_xprt_ops xs_local_ops = { + .reserve_xprt = xprt_reserve_xprt, + .release_xprt = xs_tcp_release_xprt, ++ .alloc_slot = xprt_alloc_slot, + .rpcbind = xs_local_rpcbind, + .set_port = xs_local_set_port, + .connect = xs_connect, +@@ -2449,6 +2450,7 @@ static struct rpc_xprt_ops xs_udp_ops = + .set_buffer_size = xs_udp_set_buffer_size, + .reserve_xprt = xprt_reserve_xprt_cong, + .release_xprt = xprt_release_xprt_cong, ++ .alloc_slot = xprt_alloc_slot, + .rpcbind = rpcb_getport_async, + .set_port = xs_set_port, + .connect = xs_connect, +@@ -2466,6 +2468,7 @@ static struct rpc_xprt_ops xs_udp_ops = + static struct rpc_xprt_ops xs_tcp_ops = { + .reserve_xprt = xprt_reserve_xprt, + .release_xprt = xs_tcp_release_xprt, ++ .alloc_slot = xprt_lock_and_alloc_slot, + .rpcbind = rpcb_getport_async, + .set_port = xs_set_port, + .connect = xs_connect, diff --git a/queue-3.5/usb-chipidea-udc-add-pullup-fuction-needed-by-the-uvc-gadget.patch b/queue-3.5/usb-chipidea-udc-add-pullup-fuction-needed-by-the-uvc-gadget.patch new file mode 100644 index 00000000000..1e22850d1eb --- /dev/null +++ b/queue-3.5/usb-chipidea-udc-add-pullup-fuction-needed-by-the-uvc-gadget.patch @@ -0,0 +1,72 @@ +From c0a48e6c75f2ac190d812bea5fc339696e434c2e Mon Sep 17 00:00:00 2001 +From: Michael Grzeschik +Date: Wed, 12 Sep 2012 14:58:01 +0300 +Subject: usb: chipidea: udc: add pullup fuction, needed by the uvc gadget + +From: Michael Grzeschik + +commit c0a48e6c75f2ac190d812bea5fc339696e434c2e upstream. + +Add function to physicaly enable or disable of pullup connection on the USB-D+ +line. The uvc gaget will fail, if this function is not implemented. + +Signed-off-by: Michael Grzeschik +Acked-by: Felipe Balbi +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Alexander Shishkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/udc.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -77,8 +77,7 @@ static inline int ep_to_bit(struct ci13x + } + + /** +- * hw_device_state: enables/disables interrupts & starts/stops device (execute +- * without interruption) ++ * hw_device_state: enables/disables interrupts (execute without interruption) + * @dma: 0 => disable, !0 => enable and set dma engine + * + * This function returns an error code +@@ -92,7 +91,6 @@ static int hw_device_state(struct ci13xx + USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); + hw_write(udc, OP_USBCMD, USBCMD_RS, USBCMD_RS); + } else { +- hw_write(udc, OP_USBCMD, USBCMD_RS, 0); + hw_write(udc, OP_USBINTR, ~0, 0); + } + return 0; +@@ -1419,6 +1417,21 @@ static int ci13xxx_vbus_draw(struct usb_ + return -ENOTSUPP; + } + ++/* Change Data+ pullup status ++ * this func is used by usb_gadget_connect/disconnet ++ */ ++static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) ++{ ++ struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); ++ ++ if (is_on) ++ hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); ++ else ++ hw_write(ci, OP_USBCMD, USBCMD_RS, 0); ++ ++ return 0; ++} ++ + static int ci13xxx_start(struct usb_gadget *gadget, + struct usb_gadget_driver *driver); + static int ci13xxx_stop(struct usb_gadget *gadget, +@@ -1431,6 +1444,7 @@ static int ci13xxx_stop(struct usb_gadge + static const struct usb_gadget_ops usb_gadget_ops = { + .vbus_session = ci13xxx_vbus_session, + .wakeup = ci13xxx_wakeup, ++ .pullup = ci13xxx_pullup, + .vbus_draw = ci13xxx_vbus_draw, + .udc_start = ci13xxx_start, + .udc_stop = ci13xxx_stop, diff --git a/queue-3.5/usb-gadget-at91udc-don-t-check-for-ep-ep.desc.patch b/queue-3.5/usb-gadget-at91udc-don-t-check-for-ep-ep.desc.patch new file mode 100644 index 00000000000..700b85f4d66 --- /dev/null +++ b/queue-3.5/usb-gadget-at91udc-don-t-check-for-ep-ep.desc.patch @@ -0,0 +1,48 @@ +From f3bb8e63a8ee0398dffe412e774d8801db7e1bf1 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Fri, 20 Jul 2012 20:34:25 +0200 +Subject: usb: gadget: at91udc: Don't check for ep->ep.desc + +From: Sebastian Andrzej Siewior + +commit f3bb8e63a8ee0398dffe412e774d8801db7e1bf1 upstream. + +Earlier we used to check for ep->ep.desc to figure out if this ep has +already been enabled and if so, abort. +Ido Shayevitz removed the usb_endpoint_descriptor from private udc +structure 5a6506f00 ("usb: gadget: Update at91_udc to use +usb_endpoint_descriptor inside the struct usb_ep") but did not fix up +the ep_enable condition because _now_ the member is always true and we +can't check if this ep is enabled twice. + +Cc: Ido Shayevitz +Tested-by: Fabio Porcedda +Tested-by: Mario Isidoro +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/at91_udc.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/usb/gadget/at91_udc.c ++++ b/drivers/usb/gadget/at91_udc.c +@@ -475,8 +475,7 @@ static int at91_ep_enable(struct usb_ep + unsigned long flags; + + if (!_ep || !ep +- || !desc || ep->ep.desc +- || _ep->name == ep0name ++ || !desc || _ep->name == ep0name + || desc->bDescriptorType != USB_DT_ENDPOINT + || (maxpacket = usb_endpoint_maxp(desc)) == 0 + || maxpacket > ep->maxpacket) { +@@ -530,7 +529,6 @@ ok: + tmp |= AT91_UDP_EPEDS; + __raw_writel(tmp, ep->creg); + +- ep->ep.desc = desc; + ep->ep.maxpacket = maxpacket; + + /* diff --git a/queue-3.5/usb-gadget-at91udc-don-t-overwrite-driver-data.patch b/queue-3.5/usb-gadget-at91udc-don-t-overwrite-driver-data.patch new file mode 100644 index 00000000000..5a71baa4f75 --- /dev/null +++ b/queue-3.5/usb-gadget-at91udc-don-t-overwrite-driver-data.patch @@ -0,0 +1,43 @@ +From 8b7dda554cf61e87523dee412eaf598f8646bd79 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Fri, 20 Jul 2012 20:34:24 +0200 +Subject: usb: gadget: at91udc: don't overwrite driver data + +From: Sebastian Andrzej Siewior + +commit 8b7dda554cf61e87523dee412eaf598f8646bd79 upstream. + +The driver was converted to the new start/stop interface in f3d8bf34c2 +("usb: gadget: at91_udc: convert to new style start/stop interface"). +I overlooked that the driver is overwritting the private data which is +used by the composite framework. The udc driver doesn't read it, it is +only written here. + +Tested-by: Fabio Porcedda +Tested-by: Mario Isidoro +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/at91_udc.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/gadget/at91_udc.c ++++ b/drivers/usb/gadget/at91_udc.c +@@ -1634,7 +1634,6 @@ static int at91_start(struct usb_gadget + udc = container_of(gadget, struct at91_udc, gadget); + udc->driver = driver; + udc->gadget.dev.driver = &driver->driver; +- dev_set_drvdata(&udc->gadget.dev, &driver->driver); + udc->enabled = 1; + udc->selfpowered = 1; + +@@ -1655,7 +1654,6 @@ static int at91_stop(struct usb_gadget * + spin_unlock_irqrestore(&udc->lock, flags); + + udc->gadget.dev.driver = NULL; +- dev_set_drvdata(&udc->gadget.dev, NULL); + udc->driver = NULL; + + DBG("unbound from %s\n", driver->driver.name); diff --git a/queue-3.5/usb-gadget-dummy_hcd-add-support-for-usb_dt_bos-on-rh.patch b/queue-3.5/usb-gadget-dummy_hcd-add-support-for-usb_dt_bos-on-rh.patch new file mode 100644 index 00000000000..c6c398659c0 --- /dev/null +++ b/queue-3.5/usb-gadget-dummy_hcd-add-support-for-usb_dt_bos-on-rh.patch @@ -0,0 +1,69 @@ +From 3b9c1c5ba7a95caae8440ea47308496b14f7301a Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Sun, 19 Aug 2012 21:54:59 +0200 +Subject: usb: gadget: dummy_hcd: add support for USB_DT_BOS on rh + +From: Sebastian Andrzej Siewior + +commit 3b9c1c5ba7a95caae8440ea47308496b14f7301a upstream. + +Without a reply for USB_DT_BOS the USB3 mode does not work since +448b6eb1 ("USB: Make sure to fetch the BOS desc for roothubs.). + +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/dummy_hcd.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- a/drivers/usb/gadget/dummy_hcd.c ++++ b/drivers/usb/gadget/dummy_hcd.c +@@ -1916,6 +1916,27 @@ done: + return retval; + } + ++/* usb 3.0 root hub device descriptor */ ++struct { ++ struct usb_bos_descriptor bos; ++ struct usb_ss_cap_descriptor ss_cap; ++} __packed usb3_bos_desc = { ++ ++ .bos = { ++ .bLength = USB_DT_BOS_SIZE, ++ .bDescriptorType = USB_DT_BOS, ++ .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), ++ .bNumDeviceCaps = 1, ++ }, ++ .ss_cap = { ++ .bLength = USB_DT_USB_SS_CAP_SIZE, ++ .bDescriptorType = USB_DT_DEVICE_CAPABILITY, ++ .bDevCapabilityType = USB_SS_CAP_TYPE, ++ .wSpeedSupported = cpu_to_le16(USB_5GBPS_OPERATION), ++ .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), ++ }, ++}; ++ + static inline void + ss_hub_descriptor(struct usb_hub_descriptor *desc) + { +@@ -2006,6 +2027,18 @@ static int dummy_hub_control( + else + hub_descriptor((struct usb_hub_descriptor *) buf); + break; ++ ++ case DeviceRequest | USB_REQ_GET_DESCRIPTOR: ++ if (hcd->speed != HCD_USB3) ++ goto error; ++ ++ if ((wValue >> 8) != USB_DT_BOS) ++ goto error; ++ ++ memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc)); ++ retval = sizeof(usb3_bos_desc); ++ break; ++ + case GetHubStatus: + *(__le32 *) buf = cpu_to_le32(0); + break; diff --git a/queue-3.5/usb-gadget-dummy_hcd-fixup-error-probe-path.patch b/queue-3.5/usb-gadget-dummy_hcd-fixup-error-probe-path.patch new file mode 100644 index 00000000000..236063a89a3 --- /dev/null +++ b/queue-3.5/usb-gadget-dummy_hcd-fixup-error-probe-path.patch @@ -0,0 +1,50 @@ +From 1b68a4ca2d038addb7314211d122fb6d7002b38b Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Sun, 19 Aug 2012 21:54:58 +0200 +Subject: usb: gadget: dummy_hcd: fixup error probe path + +From: Sebastian Andrzej Siewior + +commit 1b68a4ca2d038addb7314211d122fb6d7002b38b upstream. + +If USB2 host controller probes fine but USB3 does not then we don't +remove the USB controller properly and lock up the system while the HUB +code will try to enumerate the USB2 controller and access memory which +is no longer available in case the dummy_hcd was compiled as a module. + +This is a problem since 448b6eb1 ("USB: Make sure to fetch the BOS desc +for roothubs.) if used in USB3 mode because dummy does not provide this +descriptor and explodes later. + +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/dummy_hcd.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/dummy_hcd.c ++++ b/drivers/usb/gadget/dummy_hcd.c +@@ -2503,10 +2503,8 @@ static int dummy_hcd_probe(struct platfo + hs_hcd->has_tt = 1; + + retval = usb_add_hcd(hs_hcd, 0, 0); +- if (retval != 0) { +- usb_put_hcd(hs_hcd); +- return retval; +- } ++ if (retval) ++ goto put_usb2_hcd; + + if (mod_data.is_super_speed) { + ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, +@@ -2525,6 +2523,8 @@ static int dummy_hcd_probe(struct platfo + put_usb3_hcd: + usb_put_hcd(ss_hcd); + dealloc_usb2_hcd: ++ usb_remove_hcd(hs_hcd); ++put_usb2_hcd: + usb_put_hcd(hs_hcd); + the_controller.hs_hcd = the_controller.ss_hcd = NULL; + return retval;