diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-11-05 11:43:34 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2008-04-29 10:50:41 -0400 |
| commit | 251cb0bc795f5c0d8ca27df093319e5b39966174 (patch) | |
| tree | 2ac0efa68dfa9f43dda278a1df15386260164257 | |
| parent | 78eed028f13b1a0b2612368dff3786e400e6cf8b (diff) | |
ACPI: video - properly handle errors when registering proc elements
Have acpi_video_device_add_fs() and acpi_video_bus_add_fs()
properly unwind proc creation after error.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Acked-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/acpi/video.c | 230 |
1 files changed, 115 insertions, 115 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 3f0e4bccf9db..87ae791781ab 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -1048,87 +1048,90 @@ acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file) | |||
| 1048 | 1048 | ||
| 1049 | static int acpi_video_device_add_fs(struct acpi_device *device) | 1049 | static int acpi_video_device_add_fs(struct acpi_device *device) |
| 1050 | { | 1050 | { |
| 1051 | struct proc_dir_entry *entry = NULL; | 1051 | struct proc_dir_entry *entry, *device_dir; |
| 1052 | struct acpi_video_device *vid_dev; | 1052 | struct acpi_video_device *vid_dev; |
| 1053 | 1053 | ||
| 1054 | |||
| 1055 | if (!device) | ||
| 1056 | return -ENODEV; | ||
| 1057 | |||
| 1058 | vid_dev = acpi_driver_data(device); | 1054 | vid_dev = acpi_driver_data(device); |
| 1059 | if (!vid_dev) | 1055 | if (!vid_dev) |
| 1060 | return -ENODEV; | 1056 | return -ENODEV; |
| 1061 | 1057 | ||
| 1062 | if (!acpi_device_dir(device)) { | 1058 | device_dir = proc_mkdir(acpi_device_bid(device), |
| 1063 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 1059 | vid_dev->video->dir); |
| 1064 | vid_dev->video->dir); | 1060 | if (!device_dir) |
| 1065 | if (!acpi_device_dir(device)) | 1061 | return -ENOMEM; |
| 1066 | return -ENODEV; | 1062 | |
| 1067 | acpi_device_dir(device)->owner = THIS_MODULE; | 1063 | device_dir->owner = THIS_MODULE; |
| 1068 | } | ||
| 1069 | 1064 | ||
| 1070 | /* 'info' [R] */ | 1065 | /* 'info' [R] */ |
| 1071 | entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); | 1066 | entry = create_proc_entry("info", S_IRUGO, device_dir); |
| 1072 | if (!entry) | 1067 | if (!entry) |
| 1073 | return -ENODEV; | 1068 | goto err_remove_dir; |
| 1074 | else { | 1069 | |
| 1075 | entry->proc_fops = &acpi_video_device_info_fops; | 1070 | entry->proc_fops = &acpi_video_device_info_fops; |
| 1076 | entry->data = acpi_driver_data(device); | 1071 | entry->data = acpi_driver_data(device); |
| 1077 | entry->owner = THIS_MODULE; | 1072 | entry->owner = THIS_MODULE; |
| 1078 | } | ||
| 1079 | 1073 | ||
| 1080 | /* 'state' [R/W] */ | 1074 | /* 'state' [R/W] */ |
| 1081 | entry = | 1075 | entry = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR, |
| 1082 | create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR, | 1076 | device_dir); |
| 1083 | acpi_device_dir(device)); | ||
| 1084 | if (!entry) | 1077 | if (!entry) |
| 1085 | return -ENODEV; | 1078 | goto err_remove_info; |
| 1086 | else { | 1079 | |
| 1087 | acpi_video_device_state_fops.write = acpi_video_device_write_state; | 1080 | acpi_video_device_state_fops.write = acpi_video_device_write_state; |
| 1088 | entry->proc_fops = &acpi_video_device_state_fops; | 1081 | entry->proc_fops = &acpi_video_device_state_fops; |
| 1089 | entry->data = acpi_driver_data(device); | 1082 | entry->data = acpi_driver_data(device); |
| 1090 | entry->owner = THIS_MODULE; | 1083 | entry->owner = THIS_MODULE; |
| 1091 | } | ||
| 1092 | 1084 | ||
| 1093 | /* 'brightness' [R/W] */ | 1085 | /* 'brightness' [R/W] */ |
| 1094 | entry = | 1086 | entry = create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR, |
| 1095 | create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR, | 1087 | device_dir); |
| 1096 | acpi_device_dir(device)); | ||
| 1097 | if (!entry) | 1088 | if (!entry) |
| 1098 | return -ENODEV; | 1089 | goto err_remove_state; |
| 1099 | else { | 1090 | |
| 1100 | acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness; | 1091 | acpi_video_device_brightness_fops.write = |
| 1101 | entry->proc_fops = &acpi_video_device_brightness_fops; | 1092 | acpi_video_device_write_brightness; |
| 1102 | entry->data = acpi_driver_data(device); | 1093 | entry->proc_fops = &acpi_video_device_brightness_fops; |
| 1103 | entry->owner = THIS_MODULE; | 1094 | entry->data = acpi_driver_data(device); |
| 1104 | } | 1095 | entry->owner = THIS_MODULE; |
| 1105 | 1096 | ||
| 1106 | /* 'EDID' [R] */ | 1097 | /* 'EDID' [R] */ |
| 1107 | entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device)); | 1098 | entry = create_proc_entry("EDID", S_IRUGO, device_dir); |
| 1108 | if (!entry) | 1099 | if (!entry) |
| 1109 | return -ENODEV; | 1100 | goto err_remove_brightness; |
| 1110 | else { | ||
| 1111 | entry->proc_fops = &acpi_video_device_EDID_fops; | ||
| 1112 | entry->data = acpi_driver_data(device); | ||
| 1113 | entry->owner = THIS_MODULE; | ||
| 1114 | } | ||
| 1115 | 1101 | ||
| 1102 | entry->proc_fops = &acpi_video_device_EDID_fops; | ||
| 1103 | entry->data = acpi_driver_data(device); | ||
| 1104 | entry->owner = THIS_MODULE; | ||
| 1105 | |||
| 1106 | acpi_device_dir(device) = device_dir; | ||
| 1116 | return 0; | 1107 | return 0; |
| 1108 | |||
| 1109 | err_remove_brightness: | ||
| 1110 | remove_proc_entry("brightness", device_dir); | ||
| 1111 | err_remove_state: | ||
| 1112 | remove_proc_entry("state", device_dir); | ||
| 1113 | err_remove_info: | ||
| 1114 | remove_proc_entry("info", device_dir); | ||
| 1115 | err_remove_dir: | ||
| 1116 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); | ||
| 1117 | return -ENOMEM; | ||
| 1117 | } | 1118 | } |
| 1118 | 1119 | ||
| 1119 | static int acpi_video_device_remove_fs(struct acpi_device *device) | 1120 | static int acpi_video_device_remove_fs(struct acpi_device *device) |
| 1120 | { | 1121 | { |
| 1121 | struct acpi_video_device *vid_dev; | 1122 | struct acpi_video_device *vid_dev; |
| 1123 | struct proc_dir_entry *device_dir; | ||
| 1122 | 1124 | ||
| 1123 | vid_dev = acpi_driver_data(device); | 1125 | vid_dev = acpi_driver_data(device); |
| 1124 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) | 1126 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) |
| 1125 | return -ENODEV; | 1127 | return -ENODEV; |
| 1126 | 1128 | ||
| 1127 | if (acpi_device_dir(device)) { | 1129 | device_dir = acpi_device_dir(device); |
| 1128 | remove_proc_entry("info", acpi_device_dir(device)); | 1130 | if (device_dir) { |
| 1129 | remove_proc_entry("state", acpi_device_dir(device)); | 1131 | remove_proc_entry("info", device_dir); |
| 1130 | remove_proc_entry("brightness", acpi_device_dir(device)); | 1132 | remove_proc_entry("state", device_dir); |
| 1131 | remove_proc_entry("EDID", acpi_device_dir(device)); | 1133 | remove_proc_entry("brightness", device_dir); |
| 1134 | remove_proc_entry("EDID", device_dir); | ||
| 1132 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); | 1135 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); |
| 1133 | acpi_device_dir(device) = NULL; | 1136 | acpi_device_dir(device) = NULL; |
| 1134 | } | 1137 | } |
| @@ -1335,94 +1338,91 @@ acpi_video_bus_write_DOS(struct file *file, | |||
| 1335 | 1338 | ||
| 1336 | static int acpi_video_bus_add_fs(struct acpi_device *device) | 1339 | static int acpi_video_bus_add_fs(struct acpi_device *device) |
| 1337 | { | 1340 | { |
| 1338 | struct proc_dir_entry *entry = NULL; | 1341 | struct acpi_video_bus *video = acpi_driver_data(device); |
| 1339 | struct acpi_video_bus *video; | 1342 | struct proc_dir_entry *device_dir; |
| 1340 | 1343 | struct proc_dir_entry *entry; | |
| 1341 | 1344 | ||
| 1342 | video = acpi_driver_data(device); | 1345 | device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir); |
| 1346 | if (!device_dir) | ||
| 1347 | return -ENOMEM; | ||
| 1343 | 1348 | ||
| 1344 | if (!acpi_device_dir(device)) { | 1349 | device_dir->owner = THIS_MODULE; |
| 1345 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
| 1346 | acpi_video_dir); | ||
| 1347 | if (!acpi_device_dir(device)) | ||
| 1348 | return -ENODEV; | ||
| 1349 | video->dir = acpi_device_dir(device); | ||
| 1350 | acpi_device_dir(device)->owner = THIS_MODULE; | ||
| 1351 | } | ||
| 1352 | 1350 | ||
| 1353 | /* 'info' [R] */ | 1351 | /* 'info' [R] */ |
| 1354 | entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); | 1352 | entry = create_proc_entry("info", S_IRUGO, device_dir); |
| 1355 | if (!entry) | 1353 | if (!entry) |
| 1356 | return -ENODEV; | 1354 | goto err_remove_dir; |
| 1357 | else { | 1355 | |
| 1358 | entry->proc_fops = &acpi_video_bus_info_fops; | 1356 | entry->proc_fops = &acpi_video_bus_info_fops; |
| 1359 | entry->data = acpi_driver_data(device); | 1357 | entry->data = acpi_driver_data(device); |
| 1360 | entry->owner = THIS_MODULE; | 1358 | entry->owner = THIS_MODULE; |
| 1361 | } | ||
| 1362 | 1359 | ||
| 1363 | /* 'ROM' [R] */ | 1360 | /* 'ROM' [R] */ |
| 1364 | entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device)); | 1361 | entry = create_proc_entry("ROM", S_IRUGO, device_dir); |
| 1365 | if (!entry) | 1362 | if (!entry) |
| 1366 | return -ENODEV; | 1363 | goto err_remove_info; |
| 1367 | else { | 1364 | |
| 1368 | entry->proc_fops = &acpi_video_bus_ROM_fops; | 1365 | entry->proc_fops = &acpi_video_bus_ROM_fops; |
| 1369 | entry->data = acpi_driver_data(device); | 1366 | entry->data = acpi_driver_data(device); |
| 1370 | entry->owner = THIS_MODULE; | 1367 | entry->owner = THIS_MODULE; |
| 1371 | } | ||
| 1372 | 1368 | ||
| 1373 | /* 'POST_info' [R] */ | 1369 | /* 'POST_info' [R] */ |
| 1374 | entry = | 1370 | entry = create_proc_entry("POST_info", S_IRUGO, device_dir); |
| 1375 | create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device)); | ||
| 1376 | if (!entry) | 1371 | if (!entry) |
| 1377 | return -ENODEV; | 1372 | goto err_remove_rom; |
| 1378 | else { | 1373 | |
| 1379 | entry->proc_fops = &acpi_video_bus_POST_info_fops; | 1374 | entry->proc_fops = &acpi_video_bus_POST_info_fops; |
| 1380 | entry->data = acpi_driver_data(device); | 1375 | entry->data = acpi_driver_data(device); |
| 1381 | entry->owner = THIS_MODULE; | 1376 | entry->owner = THIS_MODULE; |
| 1382 | } | ||
| 1383 | 1377 | ||
| 1384 | /* 'POST' [R/W] */ | 1378 | /* 'POST' [R/W] */ |
| 1385 | entry = | 1379 | entry = create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR, |
| 1386 | create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR, | 1380 | device_dir); |
| 1387 | acpi_device_dir(device)); | ||
| 1388 | if (!entry) | 1381 | if (!entry) |
| 1389 | return -ENODEV; | 1382 | goto err_remove_post_info; |
| 1390 | else { | 1383 | |
| 1391 | acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; | 1384 | acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; |
| 1392 | entry->proc_fops = &acpi_video_bus_POST_fops; | 1385 | entry->proc_fops = &acpi_video_bus_POST_fops; |
| 1393 | entry->data = acpi_driver_data(device); | 1386 | entry->data = acpi_driver_data(device); |
| 1394 | entry->owner = THIS_MODULE; | 1387 | entry->owner = THIS_MODULE; |
| 1395 | } | ||
| 1396 | 1388 | ||
| 1397 | /* 'DOS' [R/W] */ | 1389 | /* 'DOS' [R/W] */ |
| 1398 | entry = | 1390 | entry = create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR, |
| 1399 | create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR, | 1391 | device_dir); |
| 1400 | acpi_device_dir(device)); | ||
| 1401 | if (!entry) | 1392 | if (!entry) |
| 1402 | return -ENODEV; | 1393 | goto err_remove_post; |
| 1403 | else { | 1394 | |
| 1404 | acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; | 1395 | acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; |
| 1405 | entry->proc_fops = &acpi_video_bus_DOS_fops; | 1396 | entry->proc_fops = &acpi_video_bus_DOS_fops; |
| 1406 | entry->data = acpi_driver_data(device); | 1397 | entry->data = acpi_driver_data(device); |
| 1407 | entry->owner = THIS_MODULE; | 1398 | entry->owner = THIS_MODULE; |
| 1408 | } | ||
| 1409 | 1399 | ||
| 1400 | video->dir = acpi_device_dir(device) = device_dir; | ||
| 1410 | return 0; | 1401 | return 0; |
| 1402 | |||
| 1403 | err_remove_post: | ||
| 1404 | remove_proc_entry("POST", device_dir); | ||
| 1405 | err_remove_post_info: | ||
| 1406 | remove_proc_entry("POST_info", device_dir); | ||
| 1407 | err_remove_rom: | ||
| 1408 | remove_proc_entry("ROM", device_dir); | ||
| 1409 | err_remove_info: | ||
| 1410 | remove_proc_entry("info", device_dir); | ||
| 1411 | err_remove_dir: | ||
| 1412 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); | ||
| 1413 | return -ENOMEM; | ||
| 1411 | } | 1414 | } |
| 1412 | 1415 | ||
| 1413 | static int acpi_video_bus_remove_fs(struct acpi_device *device) | 1416 | static int acpi_video_bus_remove_fs(struct acpi_device *device) |
| 1414 | { | 1417 | { |
| 1415 | struct acpi_video_bus *video; | 1418 | struct proc_dir_entry *device_dir = acpi_device_dir(device); |
| 1416 | |||
| 1417 | |||
| 1418 | video = acpi_driver_data(device); | ||
| 1419 | 1419 | ||
| 1420 | if (acpi_device_dir(device)) { | 1420 | if (device_dir) { |
| 1421 | remove_proc_entry("info", acpi_device_dir(device)); | 1421 | remove_proc_entry("info", device_dir); |
| 1422 | remove_proc_entry("ROM", acpi_device_dir(device)); | 1422 | remove_proc_entry("ROM", device_dir); |
| 1423 | remove_proc_entry("POST_info", acpi_device_dir(device)); | 1423 | remove_proc_entry("POST_info", device_dir); |
| 1424 | remove_proc_entry("POST", acpi_device_dir(device)); | 1424 | remove_proc_entry("POST", device_dir); |
| 1425 | remove_proc_entry("DOS", acpi_device_dir(device)); | 1425 | remove_proc_entry("DOS", device_dir); |
| 1426 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); | 1426 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); |
| 1427 | acpi_device_dir(device) = NULL; | 1427 | acpi_device_dir(device) = NULL; |
| 1428 | } | 1428 | } |
