diff options
author | David Hubbard <david.c.hubbard@gmail.com> | 2006-09-24 15:04:38 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-28 18:31:17 -0400 |
commit | c18beb5b92b090cb424718a4f1771b1a9fad56de (patch) | |
tree | 7fd1a129f13710d9273a71cf4d514199abd97944 /drivers/hwmon | |
parent | f3722d5b6a474e31237d23980e9bd38facfda6f4 (diff) |
w83627ehf: Fix unchecked return status
w83627ehf: Fix unchecked return status
Fix: check return value from device_create_file()
Fix: call device_remove_file() on error and module unload
Fix: call hwmon_device_register() after device_create_file() to eliminate race
Signed-off-by: David Hubbard <david.c.hubbard@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 122 |
1 files changed, 82 insertions, 40 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 23824183e02f..7a58b079d735 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -4,6 +4,7 @@ | |||
4 | Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | 4 | Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> |
5 | Copyright (C) 2006 Yuan Mu <Ymu@Winbond.com.tw>, | 5 | Copyright (C) 2006 Yuan Mu <Ymu@Winbond.com.tw>, |
6 | Rudolf Marek <r.marek@sh.cvut.cz> | 6 | Rudolf Marek <r.marek@sh.cvut.cz> |
7 | David Hubbard <david.c.hubbard@gmail.com> | ||
7 | 8 | ||
8 | Shamelessly ripped from the w83627hf driver | 9 | Shamelessly ripped from the w83627hf driver |
9 | Copyright (C) 2003 Mark Studebaker | 10 | Copyright (C) 2003 Mark Studebaker |
@@ -621,14 +622,6 @@ static struct sensor_device_attribute sda_in_max[] = { | |||
621 | SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), | 622 | SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), |
622 | }; | 623 | }; |
623 | 624 | ||
624 | static void device_create_file_in(struct device *dev, int i) | ||
625 | { | ||
626 | device_create_file(dev, &sda_in_input[i].dev_attr); | ||
627 | device_create_file(dev, &sda_in_alarm[i].dev_attr); | ||
628 | device_create_file(dev, &sda_in_min[i].dev_attr); | ||
629 | device_create_file(dev, &sda_in_max[i].dev_attr); | ||
630 | } | ||
631 | |||
632 | #define show_fan_reg(reg) \ | 625 | #define show_fan_reg(reg) \ |
633 | static ssize_t \ | 626 | static ssize_t \ |
634 | show_##reg(struct device *dev, struct device_attribute *attr, \ | 627 | show_##reg(struct device *dev, struct device_attribute *attr, \ |
@@ -756,14 +749,6 @@ static struct sensor_device_attribute sda_fan_div[] = { | |||
756 | SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), | 749 | SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), |
757 | }; | 750 | }; |
758 | 751 | ||
759 | static void device_create_file_fan(struct device *dev, int i) | ||
760 | { | ||
761 | device_create_file(dev, &sda_fan_input[i].dev_attr); | ||
762 | device_create_file(dev, &sda_fan_alarm[i].dev_attr); | ||
763 | device_create_file(dev, &sda_fan_div[i].dev_attr); | ||
764 | device_create_file(dev, &sda_fan_min[i].dev_attr); | ||
765 | } | ||
766 | |||
767 | #define show_temp1_reg(reg) \ | 752 | #define show_temp1_reg(reg) \ |
768 | static ssize_t \ | 753 | static ssize_t \ |
769 | show_##reg(struct device *dev, struct device_attribute *attr, \ | 754 | show_##reg(struct device *dev, struct device_attribute *attr, \ |
@@ -1036,15 +1021,6 @@ static struct sensor_device_attribute sda_tolerance[] = { | |||
1036 | store_tolerance, 3), | 1021 | store_tolerance, 3), |
1037 | }; | 1022 | }; |
1038 | 1023 | ||
1039 | static void device_create_file_pwm(struct device *dev, int i) | ||
1040 | { | ||
1041 | device_create_file(dev, &sda_pwm[i].dev_attr); | ||
1042 | device_create_file(dev, &sda_pwm_mode[i].dev_attr); | ||
1043 | device_create_file(dev, &sda_pwm_enable[i].dev_attr); | ||
1044 | device_create_file(dev, &sda_target_temp[i].dev_attr); | ||
1045 | device_create_file(dev, &sda_tolerance[i].dev_attr); | ||
1046 | } | ||
1047 | |||
1048 | /* Smart Fan registers */ | 1024 | /* Smart Fan registers */ |
1049 | 1025 | ||
1050 | #define fan_functions(reg, REG) \ | 1026 | #define fan_functions(reg, REG) \ |
@@ -1131,6 +1107,39 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { | |||
1131 | * Driver and client management | 1107 | * Driver and client management |
1132 | */ | 1108 | */ |
1133 | 1109 | ||
1110 | static void w83627ehf_device_remove_files(struct device *dev) | ||
1111 | { | ||
1112 | /* some entries in the following arrays may not have been used in | ||
1113 | * device_create_file(), but device_remove_file() will ignore them */ | ||
1114 | int i; | ||
1115 | |||
1116 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | ||
1117 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | ||
1118 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | ||
1119 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | ||
1120 | for (i = 0; i < 10; i++) { | ||
1121 | device_remove_file(dev, &sda_in_input[i].dev_attr); | ||
1122 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); | ||
1123 | device_remove_file(dev, &sda_in_min[i].dev_attr); | ||
1124 | device_remove_file(dev, &sda_in_max[i].dev_attr); | ||
1125 | } | ||
1126 | for (i = 0; i < 5; i++) { | ||
1127 | device_remove_file(dev, &sda_fan_input[i].dev_attr); | ||
1128 | device_remove_file(dev, &sda_fan_alarm[i].dev_attr); | ||
1129 | device_remove_file(dev, &sda_fan_div[i].dev_attr); | ||
1130 | device_remove_file(dev, &sda_fan_min[i].dev_attr); | ||
1131 | } | ||
1132 | for (i = 0; i < 4; i++) { | ||
1133 | device_remove_file(dev, &sda_pwm[i].dev_attr); | ||
1134 | device_remove_file(dev, &sda_pwm_mode[i].dev_attr); | ||
1135 | device_remove_file(dev, &sda_pwm_enable[i].dev_attr); | ||
1136 | device_remove_file(dev, &sda_target_temp[i].dev_attr); | ||
1137 | device_remove_file(dev, &sda_tolerance[i].dev_attr); | ||
1138 | } | ||
1139 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) | ||
1140 | device_remove_file(dev, &sda_temp[i].dev_attr); | ||
1141 | } | ||
1142 | |||
1134 | static struct i2c_driver w83627ehf_driver; | 1143 | static struct i2c_driver w83627ehf_driver; |
1135 | 1144 | ||
1136 | static void w83627ehf_init_client(struct i2c_client *client) | 1145 | static void w83627ehf_init_client(struct i2c_client *client) |
@@ -1217,37 +1226,69 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1217 | data->has_fan |= (1 << 4); | 1226 | data->has_fan |= (1 << 4); |
1218 | 1227 | ||
1219 | /* Register sysfs hooks */ | 1228 | /* Register sysfs hooks */ |
1220 | data->class_dev = hwmon_device_register(dev); | ||
1221 | if (IS_ERR(data->class_dev)) { | ||
1222 | err = PTR_ERR(data->class_dev); | ||
1223 | goto exit_detach; | ||
1224 | } | ||
1225 | |||
1226 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | 1229 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) |
1227 | device_create_file(dev, &sda_sf3_arrays[i].dev_attr); | 1230 | if ((err = device_create_file(dev, |
1231 | &sda_sf3_arrays[i].dev_attr))) | ||
1232 | goto exit_remove; | ||
1228 | 1233 | ||
1229 | /* if fan4 is enabled create the sf3 files for it */ | 1234 | /* if fan4 is enabled create the sf3 files for it */ |
1230 | if (data->has_fan & (1 << 3)) | 1235 | if (data->has_fan & (1 << 3)) |
1231 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1236 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { |
1232 | device_create_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1237 | if ((err = device_create_file(dev, |
1238 | &sda_sf3_arrays_fan4[i].dev_attr))) | ||
1239 | goto exit_remove; | ||
1240 | } | ||
1233 | 1241 | ||
1234 | for (i = 0; i < 10; i++) | 1242 | for (i = 0; i < 10; i++) |
1235 | device_create_file_in(dev, i); | 1243 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) |
1244 | || (err = device_create_file(dev, | ||
1245 | &sda_in_alarm[i].dev_attr)) | ||
1246 | || (err = device_create_file(dev, | ||
1247 | &sda_in_min[i].dev_attr)) | ||
1248 | || (err = device_create_file(dev, | ||
1249 | &sda_in_max[i].dev_attr))) | ||
1250 | goto exit_remove; | ||
1236 | 1251 | ||
1237 | for (i = 0; i < 5; i++) { | 1252 | for (i = 0; i < 5; i++) { |
1238 | if (data->has_fan & (1 << i)) { | 1253 | if (data->has_fan & (1 << i)) { |
1239 | device_create_file_fan(dev, i); | 1254 | if ((err = device_create_file(dev, |
1240 | if (i != 4) /* we have only 4 pwm */ | 1255 | &sda_fan_input[i].dev_attr)) |
1241 | device_create_file_pwm(dev, i); | 1256 | || (err = device_create_file(dev, |
1257 | &sda_fan_alarm[i].dev_attr)) | ||
1258 | || (err = device_create_file(dev, | ||
1259 | &sda_fan_div[i].dev_attr)) | ||
1260 | || (err = device_create_file(dev, | ||
1261 | &sda_fan_min[i].dev_attr))) | ||
1262 | goto exit_remove; | ||
1263 | if (i < 4 && /* w83627ehf only has 4 pwm */ | ||
1264 | ((err = device_create_file(dev, | ||
1265 | &sda_pwm[i].dev_attr)) | ||
1266 | || (err = device_create_file(dev, | ||
1267 | &sda_pwm_mode[i].dev_attr)) | ||
1268 | || (err = device_create_file(dev, | ||
1269 | &sda_pwm_enable[i].dev_attr)) | ||
1270 | || (err = device_create_file(dev, | ||
1271 | &sda_target_temp[i].dev_attr)) | ||
1272 | || (err = device_create_file(dev, | ||
1273 | &sda_tolerance[i].dev_attr)))) | ||
1274 | goto exit_remove; | ||
1242 | } | 1275 | } |
1243 | } | 1276 | } |
1244 | 1277 | ||
1245 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) | 1278 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) |
1246 | device_create_file(dev, &sda_temp[i].dev_attr); | 1279 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) |
1280 | goto exit_remove; | ||
1281 | |||
1282 | data->class_dev = hwmon_device_register(dev); | ||
1283 | if (IS_ERR(data->class_dev)) { | ||
1284 | err = PTR_ERR(data->class_dev); | ||
1285 | goto exit_remove; | ||
1286 | } | ||
1247 | 1287 | ||
1248 | return 0; | 1288 | return 0; |
1249 | 1289 | ||
1250 | exit_detach: | 1290 | exit_remove: |
1291 | w83627ehf_device_remove_files(dev); | ||
1251 | i2c_detach_client(client); | 1292 | i2c_detach_client(client); |
1252 | exit_free: | 1293 | exit_free: |
1253 | kfree(data); | 1294 | kfree(data); |
@@ -1263,6 +1304,7 @@ static int w83627ehf_detach_client(struct i2c_client *client) | |||
1263 | int err; | 1304 | int err; |
1264 | 1305 | ||
1265 | hwmon_device_unregister(data->class_dev); | 1306 | hwmon_device_unregister(data->class_dev); |
1307 | w83627ehf_device_remove_files(&client->dev); | ||
1266 | 1308 | ||
1267 | if ((err = i2c_detach_client(client))) | 1309 | if ((err = i2c_detach_client(client))) |
1268 | return err; | 1310 | return err; |