| From 2744d2fde00dc8bcc3679eb72c81a63058e90faa Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali.rohar@gmail.com> |
| Date: Sat, 18 Jun 2016 00:54:46 +0200 |
| Subject: hwmon: (dell-smm) Disallow fan_type() calls on broken machines |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Pali Rohár <pali.rohar@gmail.com> |
| |
| commit 2744d2fde00dc8bcc3679eb72c81a63058e90faa upstream. |
| |
| Some Dell machines have especially broken SMM or BIOS which cause that once |
| fan_type() is called then CPU fan speed going randomly up and down. And for |
| fixing this behaviour reboot is required. |
| |
| So this patch creates fan_type blacklist of affected Dell machines and |
| disallow fan_type() call on them to prevent that erratic behaviour. |
| |
| Old blacklist which disabled loading driver on some machines added in |
| commits a4b45b25f18d ("hwmon: (dell-smm) Blacklist Dell Studio XPS 8100") |
| and 6220f4ebd7b4 ("hwmon: (dell-smm) Blacklist Dell Studio XPS 8000") were |
| moved to FAN_TYPE blacklist. |
| |
| Reported-by: Jan C Peters <jcpeters89@gmail.com> |
| Signed-off-by: Pali Rohár <pali.rohar@gmail.com> |
| Link: https://bugzilla.kernel.org/show_bug.cgi?id=100121 |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/hwmon/dell-smm-hwmon.c | 36 +++++++++++++++++++++++++----------- |
| 1 file changed, 25 insertions(+), 11 deletions(-) |
| |
| --- a/drivers/hwmon/dell-smm-hwmon.c |
| +++ b/drivers/hwmon/dell-smm-hwmon.c |
| @@ -72,6 +72,7 @@ static u32 i8k_hwmon_flags; |
| static uint i8k_fan_mult = I8K_FAN_MULT; |
| static uint i8k_pwm_mult; |
| static uint i8k_fan_max = I8K_FAN_HIGH; |
| +static bool disallow_fan_type_call; |
| |
| #define I8K_HWMON_HAVE_TEMP1 (1 << 0) |
| #define I8K_HWMON_HAVE_TEMP2 (1 << 1) |
| @@ -240,6 +241,9 @@ static int i8k_get_fan_type(int fan) |
| { |
| struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, }; |
| |
| + if (disallow_fan_type_call) |
| + return -EINVAL; |
| + |
| regs.ebx = fan & 0xff; |
| return i8k_smm(®s) ? : regs.eax & 0xff; |
| } |
| @@ -721,6 +725,9 @@ static struct attribute *i8k_attrs[] = { |
| static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, |
| int index) |
| { |
| + if (disallow_fan_type_call && |
| + (index == 9 || index == 12)) |
| + return 0; |
| if (index >= 0 && index <= 1 && |
| !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) |
| return 0; |
| @@ -932,12 +939,14 @@ static struct dmi_system_id i8k_dmi_tabl |
| |
| MODULE_DEVICE_TABLE(dmi, i8k_dmi_table); |
| |
| -static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = { |
| +/* |
| + * On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed |
| + * randomly going up and down due to bug in Dell SMM or BIOS. Here is blacklist |
| + * of affected Dell machines for which we disallow I8K_SMM_GET_FAN_TYPE call. |
| + * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=100121 |
| + */ |
| +static struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initdata = { |
| { |
| - /* |
| - * CPU fan speed going up and down on Dell Studio XPS 8000 |
| - * for unknown reasons. |
| - */ |
| .ident = "Dell Studio XPS 8000", |
| .matches = { |
| DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| @@ -945,16 +954,19 @@ static struct dmi_system_id i8k_blacklis |
| }, |
| }, |
| { |
| - /* |
| - * CPU fan speed going up and down on Dell Studio XPS 8100 |
| - * for unknown reasons. |
| - */ |
| .ident = "Dell Studio XPS 8100", |
| .matches = { |
| DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"), |
| }, |
| }, |
| + { |
| + .ident = "Dell Inspiron 580", |
| + .matches = { |
| + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "), |
| + }, |
| + }, |
| { } |
| }; |
| |
| @@ -969,8 +981,7 @@ static int __init i8k_probe(void) |
| /* |
| * Get DMI information |
| */ |
| - if (!dmi_check_system(i8k_dmi_table) || |
| - dmi_check_system(i8k_blacklist_dmi_table)) { |
| + if (!dmi_check_system(i8k_dmi_table)) { |
| if (!ignore_dmi && !force) |
| return -ENODEV; |
| |
| @@ -981,6 +992,9 @@ static int __init i8k_probe(void) |
| i8k_get_dmi_data(DMI_BIOS_VERSION)); |
| } |
| |
| + if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) |
| + disallow_fan_type_call = true; |
| + |
| strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), |
| sizeof(bios_version)); |
| strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), |