diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2007-07-23 06:21:34 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-07-23 13:35:23 -0400 |
commit | 3b0d71170d37878bbb1203ebc3f92e36d6151a80 (patch) | |
tree | f2371d2114c40f622a3f037df04d4e1684353171 /drivers/misc | |
parent | 3cc2649b879f0e83fd51b14c82bad5f8f208591e (diff) |
ACPI: asus-laptop: Fix failure exits
> Subject : drivers/misc/asus-laptop.c:*: error: 'struct led_classdev' has no member named 'class_dev'
> References : http://lkml.org/lkml/2007/7/22/299
> Submitter : Gabriel C <nix.or.die@googlemail.com>
Fallout from f8a7c6fe14f556ca8eeddce258cb21392d0c3a2f. However, looking
at it shows that checks done in ASUS_LED_UNREGISTER() can't trigger
at all (we never get to asus_led_exit() if registration fails) and
if that registration fails, we actually leak stuff. IOW, it's worse
than just replacing class_dev with dev in there - the tests themselves
had been papering over the lousy cleanup logics.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/asus-laptop.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index f75306059971..6b89854bd3ff 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -1067,19 +1067,16 @@ static void asus_backlight_exit(void) | |||
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | #define ASUS_LED_UNREGISTER(object) \ | 1069 | #define ASUS_LED_UNREGISTER(object) \ |
1070 | if(object##_led.class_dev \ | 1070 | led_classdev_unregister(&object##_led) |
1071 | && !IS_ERR(object##_led.class_dev)) \ | ||
1072 | led_classdev_unregister(&object##_led) | ||
1073 | 1071 | ||
1074 | static void asus_led_exit(void) | 1072 | static void asus_led_exit(void) |
1075 | { | 1073 | { |
1074 | destroy_workqueue(led_workqueue); | ||
1076 | ASUS_LED_UNREGISTER(mled); | 1075 | ASUS_LED_UNREGISTER(mled); |
1077 | ASUS_LED_UNREGISTER(tled); | 1076 | ASUS_LED_UNREGISTER(tled); |
1078 | ASUS_LED_UNREGISTER(pled); | 1077 | ASUS_LED_UNREGISTER(pled); |
1079 | ASUS_LED_UNREGISTER(rled); | 1078 | ASUS_LED_UNREGISTER(rled); |
1080 | ASUS_LED_UNREGISTER(gled); | 1079 | ASUS_LED_UNREGISTER(gled); |
1081 | |||
1082 | destroy_workqueue(led_workqueue); | ||
1083 | } | 1080 | } |
1084 | 1081 | ||
1085 | static void __exit asus_laptop_exit(void) | 1082 | static void __exit asus_laptop_exit(void) |
@@ -1135,29 +1132,42 @@ static int asus_led_init(struct device *dev) | |||
1135 | 1132 | ||
1136 | rv = ASUS_LED_REGISTER(mled, dev); | 1133 | rv = ASUS_LED_REGISTER(mled, dev); |
1137 | if (rv) | 1134 | if (rv) |
1138 | return rv; | 1135 | goto out; |
1139 | 1136 | ||
1140 | rv = ASUS_LED_REGISTER(tled, dev); | 1137 | rv = ASUS_LED_REGISTER(tled, dev); |
1141 | if (rv) | 1138 | if (rv) |
1142 | return rv; | 1139 | goto out1; |
1143 | 1140 | ||
1144 | rv = ASUS_LED_REGISTER(rled, dev); | 1141 | rv = ASUS_LED_REGISTER(rled, dev); |
1145 | if (rv) | 1142 | if (rv) |
1146 | return rv; | 1143 | goto out2; |
1147 | 1144 | ||
1148 | rv = ASUS_LED_REGISTER(pled, dev); | 1145 | rv = ASUS_LED_REGISTER(pled, dev); |
1149 | if (rv) | 1146 | if (rv) |
1150 | return rv; | 1147 | goto out3; |
1151 | 1148 | ||
1152 | rv = ASUS_LED_REGISTER(gled, dev); | 1149 | rv = ASUS_LED_REGISTER(gled, dev); |
1153 | if (rv) | 1150 | if (rv) |
1154 | return rv; | 1151 | goto out4; |
1155 | 1152 | ||
1156 | led_workqueue = create_singlethread_workqueue("led_workqueue"); | 1153 | led_workqueue = create_singlethread_workqueue("led_workqueue"); |
1157 | if (!led_workqueue) | 1154 | if (!led_workqueue) |
1158 | return -ENOMEM; | 1155 | goto out5; |
1159 | 1156 | ||
1160 | return 0; | 1157 | return 0; |
1158 | out5: | ||
1159 | rv = -ENOMEM; | ||
1160 | ASUS_LED_UNREGISTER(gled); | ||
1161 | out4: | ||
1162 | ASUS_LED_UNREGISTER(pled); | ||
1163 | out3: | ||
1164 | ASUS_LED_UNREGISTER(rled); | ||
1165 | out2: | ||
1166 | ASUS_LED_UNREGISTER(tled); | ||
1167 | out1: | ||
1168 | ASUS_LED_UNREGISTER(mled); | ||
1169 | out: | ||
1170 | return rv; | ||
1161 | } | 1171 | } |
1162 | 1172 | ||
1163 | static int __init asus_laptop_init(void) | 1173 | static int __init asus_laptop_init(void) |