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: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
parent 490673dc
...@@ -6340,13 +6340,18 @@ static int __init ibm_init(struct ibm_init_struct *iibm) ...@@ -6340,13 +6340,18 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
/* Probing */ /* Probing */
static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) /* returns 0 - probe ok, or < 0 - probe error.
* Probe ok doesn't mean thinkpad found.
* On error, kfree() cleanup on tp->* is not performed, caller must do it */
static int __must_check __init get_thinkpad_model_data(
struct thinkpad_id_data *tp)
{ {
const struct dmi_device *dev = NULL; const struct dmi_device *dev = NULL;
char ec_fw_string[18]; char ec_fw_string[18];
char const *s;
if (!tp) if (!tp)
return; return -EINVAL;
memset(tp, 0, sizeof(*tp)); memset(tp, 0, sizeof(*tp));
...@@ -6355,12 +6360,14 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) ...@@ -6355,12 +6360,14 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
else if (dmi_name_in_vendors("LENOVO")) else if (dmi_name_in_vendors("LENOVO"))
tp->vendor = PCI_VENDOR_ID_LENOVO; tp->vendor = PCI_VENDOR_ID_LENOVO;
else else
return; return 0;
tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION), s = dmi_get_system_info(DMI_BIOS_VERSION);
GFP_KERNEL); tp->bios_version_str = kstrdup(s, GFP_KERNEL);
if (s && !tp->bios_version_str)
return -ENOMEM;
if (!tp->bios_version_str) if (!tp->bios_version_str)
return; return 0;
tp->bios_model = tp->bios_version_str[0] tp->bios_model = tp->bios_version_str[0]
| (tp->bios_version_str[1] << 8); | (tp->bios_version_str[1] << 8);
...@@ -6379,21 +6386,27 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) ...@@ -6379,21 +6386,27 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
if (!tp->ec_version_str)
return -ENOMEM;
tp->ec_model = ec_fw_string[0] tp->ec_model = ec_fw_string[0]
| (ec_fw_string[1] << 8); | (ec_fw_string[1] << 8);
break; break;
} }
} }
tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), s = dmi_get_system_info(DMI_PRODUCT_VERSION);
GFP_KERNEL); if (s && !strnicmp(s, "ThinkPad", 8)) {
if (tp->model_str && strnicmp(tp->model_str, "ThinkPad", 8) != 0) { tp->model_str = kstrdup(s, GFP_KERNEL);
kfree(tp->model_str); if (!tp->model_str)
tp->model_str = NULL; return -ENOMEM;
} }
tp->nummodel_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_NAME), s = dmi_get_system_info(DMI_PRODUCT_NAME);
GFP_KERNEL); tp->nummodel_str = kstrdup(s, GFP_KERNEL);
if (s && !tp->nummodel_str)
return -ENOMEM;
return 0;
} }
static int __init probe_for_thinkpad(void) static int __init probe_for_thinkpad(void)
...@@ -6656,7 +6669,13 @@ static int __init thinkpad_acpi_module_init(void) ...@@ -6656,7 +6669,13 @@ static int __init thinkpad_acpi_module_init(void)
/* Driver-level probe */ /* Driver-level probe */
get_thinkpad_model_data(&thinkpad_id); ret = get_thinkpad_model_data(&thinkpad_id);
if (ret) {
printk(TPACPI_ERR
"unable to get DMI data: %d\n", ret);
thinkpad_acpi_module_exit();
return ret;
}
ret = probe_for_thinkpad(); ret = probe_for_thinkpad();
if (ret) { if (ret) {
thinkpad_acpi_module_exit(); thinkpad_acpi_module_exit();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment