Attaching multiple wireless tablets to a system will cause a kernel
crash when both power supply nodes try to use the same name. The 3.17
kernel adds a unique suffix to the end of every device, but we can't
do that here if we want to be backwards compatible. Instead, we use the
suffix-less name only if it has not already been registered and use the
new behavior otherwise.

Fixes SF bug #248

Signed-off-by: Jason Gerecke <killert...@gmail.com>
---
 2.6.38/wacom_sys.c | 15 ++++++++++++++-
 2.6.38/wacom_wac.h |  1 +
 3.7/wacom_sys.c    | 15 ++++++++++++++-
 3.7/wacom_wac.h    |  1 +
 4 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/2.6.38/wacom_sys.c b/2.6.38/wacom_sys.c
index 350950a..c8e3834 100644
--- a/2.6.38/wacom_sys.c
+++ b/2.6.38/wacom_sys.c
@@ -11,6 +11,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/spinlock.h>
 #include "wacom_wac.h"
 #include "wacom.h"
 
@@ -1106,13 +1107,24 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
 
 static int wacom_initialize_battery(struct wacom *wacom)
 {
+       static atomic_t battery_no = ATOMIC_INIT(0);
+       static DEFINE_SPINLOCK(ps_lock);
+       unsigned long flags;
        int error = 0;
 
+       spin_lock_irqsave(&ps_lock, flags); /* Prevent potential race for the 
"wacom_battery" name */
        if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) {
+               unsigned long n = atomic_inc_return(&battery_no) - 1;
+
+               if (power_supply_get_by_name("wacom_battery"))
+                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", 
n);
+               else
+                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery");
+
                wacom->battery.properties = wacom_battery_props;
                wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
                wacom->battery.get_property = wacom_battery_get_property;
-               wacom->battery.name = "wacom_battery";
+               wacom->battery.name = wacom->wacom_wac.bat_name;
                wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
                wacom->battery.use_for_apm = 0;
 
@@ -1125,6 +1137,7 @@ static int wacom_initialize_battery(struct wacom *wacom)
                                            &wacom->usbdev->dev);
 #endif
        }
+       spin_unlock_irqrestore(&ps_lock, flags);
 
        return error;
 }
diff --git a/2.6.38/wacom_wac.h b/2.6.38/wacom_wac.h
index d1cfb09..8ed0a62 100644
--- a/2.6.38/wacom_wac.h
+++ b/2.6.38/wacom_wac.h
@@ -150,6 +150,7 @@ struct wacom_shared {
 
 struct wacom_wac {
        char name[WACOM_NAME_MAX];
+       char bat_name[WACOM_NAME_MAX];
        unsigned char *data;
        int tool[2];
        int id[2];
diff --git a/3.7/wacom_sys.c b/3.7/wacom_sys.c
index 11d6e0d..37a90eb 100644
--- a/3.7/wacom_sys.c
+++ b/3.7/wacom_sys.c
@@ -11,6 +11,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/spinlock.h>
 #include "wacom_wac.h"
 #include "wacom.h"
 
@@ -1107,13 +1108,24 @@ static int wacom_battery_get_property(struct 
power_supply *psy,
 
 static int wacom_initialize_battery(struct wacom *wacom)
 {
+       static atomic_t battery_no = ATOMIC_INIT(0);
+       static DEFINE_SPINLOCK(ps_lock);
+       unsigned long flags;
        int error = 0;
 
+       spin_lock_irqsave(&ps_lock, flags); /* Prevent potential race for the 
"wacom_battery" name */
        if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) {
+               unsigned long n = atomic_inc_return(&battery_no) - 1;
+
+               if (power_supply_get_by_name("wacom_battery"))
+                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery_%ld", 
n);
+               else
+                       sprintf(wacom->wacom_wac.bat_name, "wacom_battery");
+
                wacom->battery.properties = wacom_battery_props;
                wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
                wacom->battery.get_property = wacom_battery_get_property;
-               wacom->battery.name = "wacom_battery";
+               wacom->battery.name = wacom->wacom_wac.bat_name;
                wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
                wacom->battery.use_for_apm = 0;
 
@@ -1124,6 +1136,7 @@ static int wacom_initialize_battery(struct wacom *wacom)
                        power_supply_powers(&wacom->battery,
                                            &wacom->usbdev->dev);
        }
+       spin_unlock_irqrestore(&ps_lock, flags);
 
        return error;
 }
diff --git a/3.7/wacom_wac.h b/3.7/wacom_wac.h
index b2c9a9c..7e48728 100644
--- a/3.7/wacom_wac.h
+++ b/3.7/wacom_wac.h
@@ -150,6 +150,7 @@ struct wacom_shared {
 
 struct wacom_wac {
        char name[WACOM_NAME_MAX];
+       char bat_name[WACOM_NAME_MAX];
        unsigned char *data;
        int tool[2];
        int id[2];
-- 
2.1.1


------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to