Commit 2744d2fd authored by Pali Rohár's avatar Pali Rohár Committed by Guenter Roeck

hwmon: (dell-smm) Disallow fan_type() calls on broken machines

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 a4b45b25 ("hwmon: (dell-smm) Blacklist Dell Studio XPS 8100")
and 6220f4eb ("hwmon: (dell-smm) Blacklist Dell Studio XPS 8000") were
moved to FAN_TYPE blacklist.
Reported-by: default avatarJan C Peters <jcpeters89@gmail.com>
Signed-off-by: default avatarPali Rohár <pali.rohar@gmail.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=100121
Cc: stable@vger.kernel.org # v4.0+, will need backport
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 7613663c
...@@ -73,6 +73,7 @@ static u32 i8k_hwmon_flags; ...@@ -73,6 +73,7 @@ static u32 i8k_hwmon_flags;
static uint i8k_fan_mult = I8K_FAN_MULT; static uint i8k_fan_mult = I8K_FAN_MULT;
static uint i8k_pwm_mult; static uint i8k_pwm_mult;
static uint i8k_fan_max = I8K_FAN_HIGH; 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_TEMP1 (1 << 0)
#define I8K_HWMON_HAVE_TEMP2 (1 << 1) #define I8K_HWMON_HAVE_TEMP2 (1 << 1)
...@@ -241,6 +242,9 @@ static int i8k_get_fan_type(int fan) ...@@ -241,6 +242,9 @@ static int i8k_get_fan_type(int fan)
{ {
struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, }; struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
if (disallow_fan_type_call)
return -EINVAL;
regs.ebx = fan & 0xff; regs.ebx = fan & 0xff;
return i8k_smm(&regs) ? : regs.eax & 0xff; return i8k_smm(&regs) ? : regs.eax & 0xff;
} }
...@@ -726,6 +730,9 @@ static struct attribute *i8k_attrs[] = { ...@@ -726,6 +730,9 @@ static struct attribute *i8k_attrs[] = {
static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
int index) int index)
{ {
if (disallow_fan_type_call &&
(index == 9 || index == 12))
return 0;
if (index >= 0 && index <= 1 && if (index >= 0 && index <= 1 &&
!(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
return 0; return 0;
...@@ -937,12 +944,14 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = { ...@@ -937,12 +944,14 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
MODULE_DEVICE_TABLE(dmi, i8k_dmi_table); 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", .ident = "Dell Studio XPS 8000",
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
...@@ -950,16 +959,19 @@ static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = { ...@@ -950,16 +959,19 @@ static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
}, },
}, },
{ {
/*
* CPU fan speed going up and down on Dell Studio XPS 8100
* for unknown reasons.
*/
.ident = "Dell Studio XPS 8100", .ident = "Dell Studio XPS 8100",
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"), 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 "),
},
},
{ } { }
}; };
...@@ -974,8 +986,7 @@ static int __init i8k_probe(void) ...@@ -974,8 +986,7 @@ static int __init i8k_probe(void)
/* /*
* Get DMI information * Get DMI information
*/ */
if (!dmi_check_system(i8k_dmi_table) || if (!dmi_check_system(i8k_dmi_table)) {
dmi_check_system(i8k_blacklist_dmi_table)) {
if (!ignore_dmi && !force) if (!ignore_dmi && !force)
return -ENODEV; return -ENODEV;
...@@ -986,6 +997,9 @@ static int __init i8k_probe(void) ...@@ -986,6 +997,9 @@ static int __init i8k_probe(void)
i8k_get_dmi_data(DMI_BIOS_VERSION)); 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), strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
sizeof(bios_version)); sizeof(bios_version));
strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
......
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