aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2007-11-05 11:43:34 -0500
committerLen Brown <len.brown@intel.com>2008-04-29 10:50:41 -0400
commit251cb0bc795f5c0d8ca27df093319e5b39966174 (patch)
tree2ac0efa68dfa9f43dda278a1df15386260164257 /drivers/acpi/video.c
parent78eed028f13b1a0b2612368dff3786e400e6cf8b (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>
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c230
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
1049static int acpi_video_device_add_fs(struct acpi_device *device) 1049static 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
1119static int acpi_video_device_remove_fs(struct acpi_device *device) 1120static 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
1336static int acpi_video_bus_add_fs(struct acpi_device *device) 1339static 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
1413static int acpi_video_bus_remove_fs(struct acpi_device *device) 1416static 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 }