aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorDavid Hubbard <david.c.hubbard@gmail.com>2006-09-24 15:04:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-28 18:31:17 -0400
commitc18beb5b92b090cb424718a4f1771b1a9fad56de (patch)
tree7fd1a129f13710d9273a71cf4d514199abd97944 /drivers/hwmon
parentf3722d5b6a474e31237d23980e9bd38facfda6f4 (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.c122
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
624static 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) \
633static ssize_t \ 626static ssize_t \
634show_##reg(struct device *dev, struct device_attribute *attr, \ 627show_##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
759static 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) \
768static ssize_t \ 753static ssize_t \
769show_##reg(struct device *dev, struct device_attribute *attr, \ 754show_##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
1039static 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
1110static 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
1134static struct i2c_driver w83627ehf_driver; 1143static struct i2c_driver w83627ehf_driver;
1135 1144
1136static void w83627ehf_init_client(struct i2c_client *client) 1145static 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
1250exit_detach: 1290exit_remove:
1291 w83627ehf_device_remove_files(dev);
1251 i2c_detach_client(client); 1292 i2c_detach_client(client);
1252exit_free: 1293exit_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;