diff options
author | Andrew Morton <akpm@osdl.org> | 2006-07-10 02:34:45 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-07-10 02:34:45 -0400 |
commit | 8970bfe706345223d39d33bfce5f8b29750ab716 (patch) | |
tree | 0a1df121ce05018858e8a52df51281b8adae3c1c /drivers/acpi | |
parent | 953969ddf5b049361ed1e8471cc43dc4134d2a6f (diff) |
ACPI: SBS: fix initialization, sem2mutex
cm_sbs_sem is being downed (via acpi_ac_init->acpi_lock_ac_dir) before it is
initialised, with grave results.
- Make it a mutex
- Initialise it
- Make it static
- Clean other stuff up.
Thanks to Paul Drynoff <pauldrynoff@gmail.com> for reporting and testing.
Cc: Rich Townsend <rhdt@bartol.udel.edu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/cm_sbs.c | 46 |
1 files changed, 14 insertions, 32 deletions
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 574a75a166c5..a01ce6700bfe 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c | |||
@@ -39,50 +39,43 @@ ACPI_MODULE_NAME("cm_sbs") | |||
39 | static struct proc_dir_entry *acpi_ac_dir; | 39 | static struct proc_dir_entry *acpi_ac_dir; |
40 | static struct proc_dir_entry *acpi_battery_dir; | 40 | static struct proc_dir_entry *acpi_battery_dir; |
41 | 41 | ||
42 | static struct semaphore cm_sbs_sem; | 42 | static DEFINE_MUTEX(cm_sbs_mutex); |
43 | 43 | ||
44 | static int lock_ac_dir_cnt = 0; | 44 | static int lock_ac_dir_cnt; |
45 | static int lock_battery_dir_cnt = 0; | 45 | static int lock_battery_dir_cnt; |
46 | 46 | ||
47 | struct proc_dir_entry *acpi_lock_ac_dir(void) | 47 | struct proc_dir_entry *acpi_lock_ac_dir(void) |
48 | { | 48 | { |
49 | 49 | mutex_lock(&cm_sbs_mutex); | |
50 | down(&cm_sbs_sem); | 50 | if (!acpi_ac_dir) |
51 | if (!acpi_ac_dir) { | ||
52 | acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); | 51 | acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); |
53 | } | ||
54 | if (acpi_ac_dir) { | 52 | if (acpi_ac_dir) { |
55 | lock_ac_dir_cnt++; | 53 | lock_ac_dir_cnt++; |
56 | } else { | 54 | } else { |
57 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 55 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
58 | "Cannot create %s\n", ACPI_AC_CLASS)); | 56 | "Cannot create %s\n", ACPI_AC_CLASS)); |
59 | } | 57 | } |
60 | up(&cm_sbs_sem); | 58 | mutex_unlock(&cm_sbs_mutex); |
61 | return acpi_ac_dir; | 59 | return acpi_ac_dir; |
62 | } | 60 | } |
63 | |||
64 | EXPORT_SYMBOL(acpi_lock_ac_dir); | 61 | EXPORT_SYMBOL(acpi_lock_ac_dir); |
65 | 62 | ||
66 | void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) | 63 | void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) |
67 | { | 64 | { |
68 | 65 | mutex_lock(&cm_sbs_mutex); | |
69 | down(&cm_sbs_sem); | 66 | if (acpi_ac_dir_param) |
70 | if (acpi_ac_dir_param) { | ||
71 | lock_ac_dir_cnt--; | 67 | lock_ac_dir_cnt--; |
72 | } | ||
73 | if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { | 68 | if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { |
74 | remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); | 69 | remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); |
75 | acpi_ac_dir = 0; | 70 | acpi_ac_dir = 0; |
76 | } | 71 | } |
77 | up(&cm_sbs_sem); | 72 | mutex_unlock(&cm_sbs_mutex); |
78 | } | 73 | } |
79 | |||
80 | EXPORT_SYMBOL(acpi_unlock_ac_dir); | 74 | EXPORT_SYMBOL(acpi_unlock_ac_dir); |
81 | 75 | ||
82 | struct proc_dir_entry *acpi_lock_battery_dir(void) | 76 | struct proc_dir_entry *acpi_lock_battery_dir(void) |
83 | { | 77 | { |
84 | 78 | mutex_lock(&cm_sbs_mutex); | |
85 | down(&cm_sbs_sem); | ||
86 | if (!acpi_battery_dir) { | 79 | if (!acpi_battery_dir) { |
87 | acpi_battery_dir = | 80 | acpi_battery_dir = |
88 | proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); | 81 | proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); |
@@ -93,39 +86,28 @@ struct proc_dir_entry *acpi_lock_battery_dir(void) | |||
93 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 86 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
94 | "Cannot create %s\n", ACPI_BATTERY_CLASS)); | 87 | "Cannot create %s\n", ACPI_BATTERY_CLASS)); |
95 | } | 88 | } |
96 | up(&cm_sbs_sem); | 89 | mutex_unlock(&cm_sbs_mutex); |
97 | return acpi_battery_dir; | 90 | return acpi_battery_dir; |
98 | } | 91 | } |
99 | |||
100 | EXPORT_SYMBOL(acpi_lock_battery_dir); | 92 | EXPORT_SYMBOL(acpi_lock_battery_dir); |
101 | 93 | ||
102 | void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) | 94 | void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) |
103 | { | 95 | { |
104 | 96 | mutex_lock(&cm_sbs_mutex); | |
105 | down(&cm_sbs_sem); | 97 | if (acpi_battery_dir_param) |
106 | if (acpi_battery_dir_param) { | ||
107 | lock_battery_dir_cnt--; | 98 | lock_battery_dir_cnt--; |
108 | } | ||
109 | if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param | 99 | if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param |
110 | && acpi_battery_dir) { | 100 | && acpi_battery_dir) { |
111 | remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); | 101 | remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); |
112 | acpi_battery_dir = 0; | 102 | acpi_battery_dir = 0; |
113 | } | 103 | } |
114 | up(&cm_sbs_sem); | 104 | mutex_unlock(&cm_sbs_mutex); |
115 | return; | 105 | return; |
116 | } | 106 | } |
117 | |||
118 | EXPORT_SYMBOL(acpi_unlock_battery_dir); | 107 | EXPORT_SYMBOL(acpi_unlock_battery_dir); |
119 | 108 | ||
120 | static int __init acpi_cm_sbs_init(void) | 109 | static int __init acpi_cm_sbs_init(void) |
121 | { | 110 | { |
122 | |||
123 | if (acpi_disabled) | ||
124 | return 0; | ||
125 | |||
126 | init_MUTEX(&cm_sbs_sem); | ||
127 | |||
128 | return 0; | 111 | return 0; |
129 | } | 112 | } |
130 | |||
131 | subsys_initcall(acpi_cm_sbs_init); | 113 | subsys_initcall(acpi_cm_sbs_init); |