]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.39/patches.arch/acpi-dock-fix-hotplug-race.patch
Updated kernel (2.6.27.41).
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / acpi-dock-fix-hotplug-race.patch
diff --git a/src/patches/suse-2.6.27.39/patches.arch/acpi-dock-fix-hotplug-race.patch b/src/patches/suse-2.6.27.39/patches.arch/acpi-dock-fix-hotplug-race.patch
deleted file mode 100644 (file)
index 2a622cc..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-From: Shaohua Li <shaohua.li@intel.com>
-Subject: fix hotplug race
-Patch-mainline: submitted 2008-08-28
-References: fate#304731,bnc#401740
-
-hotplug notification handler and drivers' notification handler are all
-running in one workqueue. Before hotplug removes an acpi device, the
-device driver's notification handler is already be recorded to run just
-after global notification handler. After hotplug notification handler
-runs, acpica will notice a NULL notification handler and crash. This
-patch runs hotplug in other workqueue and wait for all acpi notication
-handlers finish. This is found in battery hotplug, but actually all
-hotplug can be affected.
-
-Signed-off-by: Zhang Rui <rui.zhang@intel.com>
-Signed-off-by: Shaohua Li <shaohua.li@intel.com>
-Signed-off-by: Holger Macht <hmacht@suse.de>
----
-
----
- drivers/acpi/dock.c     |   25 ++++++++++++++++++++++++-
- drivers/acpi/osl.c      |   46 +++++++++++++++++++++++++++++++++++++++++-----
- include/acpi/acpiosxf.h |    3 +++
- 3 files changed, 68 insertions(+), 6 deletions(-)
-
---- a/drivers/acpi/dock.c
-+++ b/drivers/acpi/dock.c
-@@ -748,6 +748,20 @@ static void dock_notify(acpi_handle hand
-       }
- }
-+struct dock_data {
-+      acpi_handle handle;
-+      unsigned long event;
-+      struct dock_station *ds;
-+};
-+
-+static void acpi_dock_deferred_cb(void *context)
-+{
-+      struct dock_data *data = (struct dock_data *)context;
-+
-+      dock_notify(data->handle, data->event, data->ds);
-+      kfree(data);
-+}
-+
- static int acpi_dock_notifier_call(struct notifier_block *this,
-       unsigned long event, void *data)
- {
-@@ -759,7 +773,16 @@ static int acpi_dock_notifier_call(struc
-               return 0;
-       list_for_each_entry(dock_station, &dock_stations, sibiling) {
-               if (dock_station->handle == handle) {
--                      dock_notify(handle, event, dock_station);
-+                      struct dock_data *dock_data;
-+
-+                      dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL);
-+                      if (!dock_data)
-+                              return 0;
-+                      dock_data->handle = handle;
-+                      dock_data->event = event;
-+                      dock_data->ds = dock_station;
-+                      acpi_os_hotplug_execute(acpi_dock_deferred_cb,
-+                              dock_data);
-                       return 0 ;
-               }
-       }
---- a/drivers/acpi/osl.c
-+++ b/drivers/acpi/osl.c
-@@ -705,6 +705,22 @@ static void acpi_os_execute_deferred(str
-       return;
- }
-+static void acpi_os_execute_hp_deferred(struct work_struct *work)
-+{
-+      struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
-+      if (!dpc) {
-+              printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-+              return;
-+      }
-+
-+      acpi_os_wait_events_complete(NULL);
-+
-+      dpc->function(dpc->context);
-+      kfree(dpc);
-+
-+      return;
-+}
-+
- /*******************************************************************************
-  *
-  * FUNCTION:    acpi_os_execute
-@@ -720,12 +736,13 @@ static void acpi_os_execute_deferred(str
-  *
-  ******************************************************************************/
--acpi_status acpi_os_execute(acpi_execute_type type,
--                          acpi_osd_exec_callback function, void *context)
-+static acpi_status __acpi_os_execute(acpi_execute_type type,
-+      acpi_osd_exec_callback function, void *context, int hp)
- {
-       acpi_status status = AE_OK;
-       struct acpi_os_dpc *dpc;
-       struct workqueue_struct *queue;
-+      int ret;
-       ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                         "Scheduling function [%p(%p)] for deferred execution.\n",
-                         function, context));
-@@ -749,9 +766,17 @@ acpi_status acpi_os_execute(acpi_execute
-       dpc->function = function;
-       dpc->context = context;
--      INIT_WORK(&dpc->work, acpi_os_execute_deferred);
--      queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq;
--      if (!queue_work(queue, &dpc->work)) {
-+      if (!hp) {
-+              INIT_WORK(&dpc->work, acpi_os_execute_deferred);
-+              queue = (type == OSL_NOTIFY_HANDLER) ?
-+                      kacpi_notify_wq : kacpid_wq;
-+              ret = queue_work(queue, &dpc->work);
-+      } else {
-+              INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred);
-+              ret = schedule_work(&dpc->work);
-+      }
-+
-+      if (!ret) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                         "Call to queue_work() failed.\n"));
-               status = AE_ERROR;
-@@ -760,8 +785,19 @@ acpi_status acpi_os_execute(acpi_execute
-       return_ACPI_STATUS(status);
- }
-+acpi_status acpi_os_execute(acpi_execute_type type,
-+                          acpi_osd_exec_callback function, void *context)
-+{
-+      return __acpi_os_execute(type, function, context, 0);
-+}
- EXPORT_SYMBOL(acpi_os_execute);
-+acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
-+      void *context)
-+{
-+      return __acpi_os_execute(0, function, context, 1);
-+}
-+
- void acpi_os_wait_events_complete(void *context)
- {
-       flush_workqueue(kacpid_wq);
---- a/include/acpi/acpiosxf.h
-+++ b/include/acpi/acpiosxf.h
-@@ -193,6 +193,9 @@ acpi_status
- acpi_os_execute(acpi_execute_type type,
-               acpi_osd_exec_callback function, void *context);
-+acpi_status
-+acpi_os_hotplug_execute(acpi_osd_exec_callback function, void *context);
-+
- void acpi_os_wait_events_complete(void *context);
- void acpi_os_sleep(acpi_integer milliseconds);