From: Greg Kroah-Hartman Date: Thu, 22 Aug 2013 21:55:55 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.0.94~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ee68aba23cec001eac24fb942cdca92733fc028e;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: acpi-add-_sta-evaluation-at-do_acpi_find_child.patch acpi-try-harder-to-resolve-_adr-collisions-for-bridges.patch mac80211-don-t-wait-for-tx-status-forever.patch --- diff --git a/queue-3.10/acpi-add-_sta-evaluation-at-do_acpi_find_child.patch b/queue-3.10/acpi-add-_sta-evaluation-at-do_acpi_find_child.patch new file mode 100644 index 00000000000..a2230adf6f9 --- /dev/null +++ b/queue-3.10/acpi-add-_sta-evaluation-at-do_acpi_find_child.patch @@ -0,0 +1,60 @@ +From c7d9ca90aa9497f0b6e301ec67c52dd4b57a7852 Mon Sep 17 00:00:00 2001 +From: Jeff Wu +Date: Wed, 29 May 2013 06:31:30 +0000 +Subject: ACPI: add _STA evaluation at do_acpi_find_child() + +From: Jeff Wu + +commit c7d9ca90aa9497f0b6e301ec67c52dd4b57a7852 upstream. + +Once do_acpi_find_child() has found the first matching handle, it +makes the acpi_get_child() loop stop and return that handle. On some +platforms, though, there are multiple devices with the same value of +"_ADR" in the same namespace scope, and if one of them is enabled, +the others will be disabled. For example: + + Address : 0x1FFFF ; path : SB_PCI0.SATA.DEV0 + Address : 0x1FFFF ; path : SB_PCI0.SATA.DEV1 + Address : 0x1FFFF ; path : SB_PCI0.SATA.DEV2 + +If DEV0 and DEV1 are disabled and DEV2 is enabled, the handle of DEV2 +should be returned, but actually the function always returns the +handle of DEV0. + +To address that issue, make do_acpi_find_child() evaluate _STA to +check the device status. If a matching device object exists, but is +disabled, acpi_get_child() will continue to walk the namespace in the +hope of finding an enabled one. If one is found, its handle will be +returned, but otherwise the function will return the handle of the +disabled object found before (in case it is enabled going forward). + +[rjw: Changelog] +Signed-off-by: Jeff Wu +Signed-off-by: Rafael J. Wysocki +Cc: Peter Wu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/glue.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/glue.c ++++ b/drivers/acpi/glue.c +@@ -81,13 +81,15 @@ static struct acpi_bus_type *acpi_get_bu + static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used, + void *addr_p, void **ret_p) + { +- unsigned long long addr; ++ unsigned long long addr, sta; + acpi_status status; + + status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); + if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) { + *ret_p = handle; +- return AE_CTRL_TERMINATE; ++ status = acpi_bus_get_status_handle(handle, &sta); ++ if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_ENABLED)) ++ return AE_CTRL_TERMINATE; + } + return AE_OK; + } diff --git a/queue-3.10/acpi-try-harder-to-resolve-_adr-collisions-for-bridges.patch b/queue-3.10/acpi-try-harder-to-resolve-_adr-collisions-for-bridges.patch new file mode 100644 index 00000000000..97ec7f96557 --- /dev/null +++ b/queue-3.10/acpi-try-harder-to-resolve-_adr-collisions-for-bridges.patch @@ -0,0 +1,243 @@ +From 60f75b8e97daf4a39790a20d962cb861b9220af5 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Wed, 7 Aug 2013 22:55:00 +0200 +Subject: ACPI: Try harder to resolve _ADR collisions for bridges + +From: "Rafael J. Wysocki" + +commit 60f75b8e97daf4a39790a20d962cb861b9220af5 upstream. + +In theory, under a given ACPI namespace node there should be only +one child device object with _ADR whose value matches a given bus +address exactly. In practice, however, there are systems in which +multiple child device objects under a given parent have _ADR matching +exactly the same address. In those cases we use _STA to determine +which of the multiple matching devices is enabled, since some systems +are known to indicate which ACPI device object to associate with the +given physical (usually PCI) device this way. + +Unfortunately, as it turns out, there are systems in which many +device objects under the same parent have _ADR matching exactly the +same bus address and none of them has _STA, in which case they all +should be regarded as enabled according to the spec. Still, if +those device objects are supposed to represent bridges (e.g. this +is the case for device objects corresponding to PCIe ports), we can +try harder and skip the ones that have no child device objects in the +ACPI namespace. With luck, we can avoid using device objects that we +are not expected to use this way. + +Although this only works for bridges whose children also have ACPI +namespace representation, it is sufficient to address graphics +adapter detection issues on some systems, so rework the code finding +a matching device ACPI handle for a given bus address to implement +this idea. + +Introduce a new function, acpi_find_child(), taking three arguments: +the ACPI handle of the device's parent, a bus address suitable for +the device's bus type and a bool indicating if the device is a +bridge and make it work as outlined above. Reimplement the function +currently used for this purpose, acpi_get_child(), as a call to +acpi_find_child() with the last argument set to 'false' and make +the PCI subsystem use acpi_find_child() with the bridge information +passed as the last argument to it. [Lan Tianyu notices that it is +not sufficient to use pci_is_bridge() for that, because the device's +subordinate pointer hasn't been set yet at this point, so use +hdr_type instead.] + +This change fixes a regression introduced inadvertently by commit +33f767d (ACPI: Rework acpi_get_child() to be more efficient) which +overlooked the fact that for acpi_walk_namespace() "post-order" means +"after all children have been visited" rather than "on the way back", +so for device objects without children and for namespace walks of +depth 1, as in the acpi_get_child() case, the "post-order" callbacks +ordering is actually the same as the ordering of "pre-order" ones. +Since that commit changed the namespace walk in acpi_get_child() to +terminate after finding the first matching object instead of going +through all of them and returning the last one, it effectively +changed the result returned by that function in some rare cases and +that led to problems (the switch from a "pre-order" to a "post-order" +callback was supposed to prevent that from happening, but it was +ineffective). + +As it turns out, the systems where the change made by commit +33f767d actually matters are those where there are multiple ACPI +device objects representing the same PCIe port (which effectively +is a bridge). Moreover, only one of them, and the one we are +expected to use, has child device objects in the ACPI namespace, +so the regression can be addressed as described above. + +References: https://bugzilla.kernel.org/show_bug.cgi?id=60561 +Reported-by: Peter Wu +Tested-by: Vladimir Lalov +Signed-off-by: Rafael J. Wysocki +Acked-by: Bjorn Helgaas +Cc: Peter Wu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/glue.c | 99 +++++++++++++++++++++++++++++++++++++++--------- + drivers/pci/pci-acpi.c | 15 +++++-- + include/acpi/acpi_bus.h | 6 ++ + 3 files changed, 98 insertions(+), 22 deletions(-) + +--- a/drivers/acpi/glue.c ++++ b/drivers/acpi/glue.c +@@ -78,34 +78,99 @@ static struct acpi_bus_type *acpi_get_bu + return ret; + } + +-static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used, +- void *addr_p, void **ret_p) ++static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used, ++ void *not_used, void **ret_p) + { +- unsigned long long addr, sta; +- acpi_status status; ++ struct acpi_device *adev = NULL; + +- status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); +- if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) { ++ acpi_bus_get_device(handle, &adev); ++ if (adev) { + *ret_p = handle; +- status = acpi_bus_get_status_handle(handle, &sta); +- if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_ENABLED)) +- return AE_CTRL_TERMINATE; ++ return AE_CTRL_TERMINATE; + } + return AE_OK; + } + +-acpi_handle acpi_get_child(acpi_handle parent, u64 address) ++static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge) + { +- void *ret = NULL; ++ unsigned long long sta; ++ acpi_status status; + +- if (!parent) +- return NULL; ++ status = acpi_bus_get_status_handle(handle, &sta); ++ if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) ++ return false; ++ ++ if (is_bridge) { ++ void *test = NULL; ++ ++ /* Check if this object has at least one child device. */ ++ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, ++ acpi_dev_present, NULL, NULL, &test); ++ return !!test; ++ } ++ return true; ++} + +- acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL, +- do_acpi_find_child, &address, &ret); +- return (acpi_handle)ret; ++struct find_child_context { ++ u64 addr; ++ bool is_bridge; ++ acpi_handle ret; ++ bool ret_checked; ++}; ++ ++static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, ++ void *data, void **not_used) ++{ ++ struct find_child_context *context = data; ++ unsigned long long addr; ++ acpi_status status; ++ ++ status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); ++ if (ACPI_FAILURE(status) || addr != context->addr) ++ return AE_OK; ++ ++ if (!context->ret) { ++ /* This is the first matching object. Save its handle. */ ++ context->ret = handle; ++ return AE_OK; ++ } ++ /* ++ * There is more than one matching object with the same _ADR value. ++ * That really is unexpected, so we are kind of beyond the scope of the ++ * spec here. We have to choose which one to return, though. ++ * ++ * First, check if the previously found object is good enough and return ++ * its handle if so. Second, check the same for the object that we've ++ * just found. ++ */ ++ if (!context->ret_checked) { ++ if (acpi_extra_checks_passed(context->ret, context->is_bridge)) ++ return AE_CTRL_TERMINATE; ++ else ++ context->ret_checked = true; ++ } ++ if (acpi_extra_checks_passed(handle, context->is_bridge)) { ++ context->ret = handle; ++ return AE_CTRL_TERMINATE; ++ } ++ return AE_OK; ++} ++ ++acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge) ++{ ++ if (parent) { ++ struct find_child_context context = { ++ .addr = addr, ++ .is_bridge = is_bridge, ++ }; ++ ++ acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, do_find_child, ++ NULL, &context, NULL); ++ return context.ret; ++ } ++ return NULL; + } +-EXPORT_SYMBOL(acpi_get_child); ++EXPORT_SYMBOL_GPL(acpi_find_child); + + static int acpi_bind_one(struct device *dev, acpi_handle handle) + { +--- a/drivers/pci/pci-acpi.c ++++ b/drivers/pci/pci-acpi.c +@@ -317,13 +317,20 @@ void acpi_pci_remove_bus(struct pci_bus + /* ACPI bus type */ + static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) + { +- struct pci_dev * pci_dev; +- u64 addr; ++ struct pci_dev *pci_dev = to_pci_dev(dev); ++ bool is_bridge; ++ u64 addr; + +- pci_dev = to_pci_dev(dev); ++ /* ++ * pci_is_bridge() is not suitable here, because pci_dev->subordinate ++ * is set only after acpi_pci_find_device() has been called for the ++ * given device. ++ */ ++ is_bridge = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ++ || pci_dev->hdr_type == PCI_HEADER_TYPE_CARDBUS; + /* Please ref to ACPI spec for the syntax of _ADR */ + addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); +- *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); ++ *handle = acpi_find_child(ACPI_HANDLE(dev->parent), addr, is_bridge); + if (!*handle) + return -ENODEV; + return 0; +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -455,7 +455,11 @@ struct acpi_pci_root { + }; + + /* helper */ +-acpi_handle acpi_get_child(acpi_handle, u64); ++acpi_handle acpi_find_child(acpi_handle, u64, bool); ++static inline acpi_handle acpi_get_child(acpi_handle handle, u64 addr) ++{ ++ return acpi_find_child(handle, addr, false); ++} + int acpi_is_root_bridge(acpi_handle); + struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); + #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev)) diff --git a/queue-3.10/mac80211-don-t-wait-for-tx-status-forever.patch b/queue-3.10/mac80211-don-t-wait-for-tx-status-forever.patch new file mode 100644 index 00000000000..ce68ddaea69 --- /dev/null +++ b/queue-3.10/mac80211-don-t-wait-for-tx-status-forever.patch @@ -0,0 +1,67 @@ +From cb236d2d713cff83d024a82b836757d9e2b50715 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 29 Jul 2013 23:07:43 +0200 +Subject: mac80211: don't wait for TX status forever + +From: Johannes Berg + +commit cb236d2d713cff83d024a82b836757d9e2b50715 upstream. + +TX status notification can get lost, or the frames could +get stuck on the queue, so don't wait for the callback +from the driver forever and instead time out after half +a second. + +Signed-off-by: Johannes Berg +Signed-off-by: Luciano Coelho +Signed-off-by: Greg Kroah-Hartman + + +--- + net/mac80211/mlme.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -31,10 +31,12 @@ + #include "led.h" + + #define IEEE80211_AUTH_TIMEOUT (HZ / 5) ++#define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2) + #define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10) + #define IEEE80211_AUTH_MAX_TRIES 3 + #define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5) + #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) ++#define IEEE80211_ASSOC_TIMEOUT_LONG (HZ / 2) + #define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10) + #define IEEE80211_ASSOC_MAX_TRIES 3 + +@@ -3470,10 +3472,13 @@ static int ieee80211_probe_auth(struct i + + if (tx_flags == 0) { + auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; +- ifmgd->auth_data->timeout_started = true; ++ auth_data->timeout_started = true; + run_again(ifmgd, auth_data->timeout); + } else { +- auth_data->timeout_started = false; ++ auth_data->timeout = ++ round_jiffies_up(jiffies + IEEE80211_AUTH_TIMEOUT_LONG); ++ auth_data->timeout_started = true; ++ run_again(ifmgd, auth_data->timeout); + } + + return 0; +@@ -3510,7 +3515,11 @@ static int ieee80211_do_assoc(struct iee + assoc_data->timeout_started = true; + run_again(&sdata->u.mgd, assoc_data->timeout); + } else { +- assoc_data->timeout_started = false; ++ assoc_data->timeout = ++ round_jiffies_up(jiffies + ++ IEEE80211_ASSOC_TIMEOUT_LONG); ++ assoc_data->timeout_started = true; ++ run_again(&sdata->u.mgd, assoc_data->timeout); + } + + return 0; diff --git a/queue-3.10/series b/queue-3.10/series index 630b59faf9c..71542fe5daf 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -1 +1,4 @@ kvm-s390-move-kvm_guest_enter-exit-closer-to-sie.patch +mac80211-don-t-wait-for-tx-status-forever.patch +acpi-add-_sta-evaluation-at-do_acpi_find_child.patch +acpi-try-harder-to-resolve-_adr-collisions-for-bridges.patch