aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2008-07-21 08:15:51 -0400
committerHenrique de Moraes Holschuh <hmh@hmh.eng.br>2008-07-21 08:15:51 -0400
commitbf20e740a4bcc686de02e2fd1c1810a58872f46e (patch)
treea3fccedd9c0da2ccdd2088de42e986430c1a4d83
parent490673dc98adfc7de1703cc88508902bd10f446b (diff)
ACPI: thinkpad-acpi: don't misdetect in get_thinkpad_model_data() on -ENOMEM
Explicitly check for memory allocation failures, and return status to indicate that we could not collect data due to errors. This lets the driver have a far more predictable failure mode on ENOMEM in that codepath: it will refuse to load. This is far better than trying to proceed with missing data which is used to detect quirks, etc. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
-rw-r--r--drivers/misc/thinkpad_acpi.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 3eb01afe4306..d3eb7903c346 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -6340,13 +6340,18 @@ err_out:
6340 6340
6341/* Probing */ 6341/* Probing */
6342 6342
6343static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) 6343/* returns 0 - probe ok, or < 0 - probe error.
6344 * Probe ok doesn't mean thinkpad found.
6345 * On error, kfree() cleanup on tp->* is not performed, caller must do it */
6346static int __must_check __init get_thinkpad_model_data(
6347 struct thinkpad_id_data *tp)
6344{ 6348{
6345 const struct dmi_device *dev = NULL; 6349 const struct dmi_device *dev = NULL;
6346 char ec_fw_string[18]; 6350 char ec_fw_string[18];
6351 char const *s;
6347 6352
6348 if (!tp) 6353 if (!tp)
6349 return; 6354 return -EINVAL;
6350 6355
6351 memset(tp, 0, sizeof(*tp)); 6356 memset(tp, 0, sizeof(*tp));
6352 6357
@@ -6355,12 +6360,14 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
6355 else if (dmi_name_in_vendors("LENOVO")) 6360 else if (dmi_name_in_vendors("LENOVO"))
6356 tp->vendor = PCI_VENDOR_ID_LENOVO; 6361 tp->vendor = PCI_VENDOR_ID_LENOVO;
6357 else 6362 else
6358 return; 6363 return 0;
6359 6364
6360 tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION), 6365 s = dmi_get_system_info(DMI_BIOS_VERSION);
6361 GFP_KERNEL); 6366 tp->bios_version_str = kstrdup(s, GFP_KERNEL);
6367 if (s && !tp->bios_version_str)
6368 return -ENOMEM;
6362 if (!tp->bios_version_str) 6369 if (!tp->bios_version_str)
6363 return; 6370 return 0;
6364 tp->bios_model = tp->bios_version_str[0] 6371 tp->bios_model = tp->bios_version_str[0]
6365 | (tp->bios_version_str[1] << 8); 6372 | (tp->bios_version_str[1] << 8);
6366 6373
@@ -6379,21 +6386,27 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
6379 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; 6386 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
6380 6387
6381 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); 6388 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
6389 if (!tp->ec_version_str)
6390 return -ENOMEM;
6382 tp->ec_model = ec_fw_string[0] 6391 tp->ec_model = ec_fw_string[0]
6383 | (ec_fw_string[1] << 8); 6392 | (ec_fw_string[1] << 8);
6384 break; 6393 break;
6385 } 6394 }
6386 } 6395 }
6387 6396
6388 tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), 6397 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
6389 GFP_KERNEL); 6398 if (s && !strnicmp(s, "ThinkPad", 8)) {
6390 if (tp->model_str && strnicmp(tp->model_str, "ThinkPad", 8) != 0) { 6399 tp->model_str = kstrdup(s, GFP_KERNEL);
6391 kfree(tp->model_str); 6400 if (!tp->model_str)
6392 tp->model_str = NULL; 6401 return -ENOMEM;
6393 } 6402 }
6394 6403
6395 tp->nummodel_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_NAME), 6404 s = dmi_get_system_info(DMI_PRODUCT_NAME);
6396 GFP_KERNEL); 6405 tp->nummodel_str = kstrdup(s, GFP_KERNEL);
6406 if (s && !tp->nummodel_str)
6407 return -ENOMEM;
6408
6409 return 0;
6397} 6410}
6398 6411
6399static int __init probe_for_thinkpad(void) 6412static int __init probe_for_thinkpad(void)
@@ -6656,7 +6669,13 @@ static int __init thinkpad_acpi_module_init(void)
6656 6669
6657 /* Driver-level probe */ 6670 /* Driver-level probe */
6658 6671
6659 get_thinkpad_model_data(&thinkpad_id); 6672 ret = get_thinkpad_model_data(&thinkpad_id);
6673 if (ret) {
6674 printk(TPACPI_ERR
6675 "unable to get DMI data: %d\n", ret);
6676 thinkpad_acpi_module_exit();
6677 return ret;
6678 }
6660 ret = probe_for_thinkpad(); 6679 ret = probe_for_thinkpad();
6661 if (ret) { 6680 if (ret) {
6662 thinkpad_acpi_module_exit(); 6681 thinkpad_acpi_module_exit();