linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] misc: lis3lv02d: Fix false-positive WARN on various HP models
@ 2021-02-17 10:24 Hans de Goede
  2021-02-17 10:25 ` [PATCH 2/3] misc: lis3lv02d: Change lis3lv02d_init_device() return value for unknown sensors to -ENODEV Hans de Goede
  2021-02-17 10:25 ` [PATCH 3/3] misc: lis3lv02d: Do not log an error when kmalloc fails Hans de Goede
  0 siblings, 2 replies; 3+ messages in thread
From: Hans de Goede @ 2021-02-17 10:24 UTC (permalink / raw)
  To: Eric Piel, Arnd Bergmann, Greg Kroah-Hartman
  Cc: Hans de Goede, linux-kernel, stable

Before this commit lis3lv02d_get_pwron_wait() had a WARN_ONCE() to catch
a potential divide by 0. WARN macros should only be used to catch internal
kernel bugs and that is not the case here. We have been receiving a lot of
bug reports about kernel backtraces caused by this WARN.

The div value being checked comes from the lis3->odrs[] array. Which
is sized to be a power-of-2 matching the number of bits in lis3->odr_mask.

The only lis3 model where this array is not entirely filled with non zero
values. IOW the only model where we can hit the div == 0 check is the
3dc ("8 bits 3DC sensor") model:

int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};

Note the 0 value at index 0, according to the datasheet an odr index of 0
means "Power-down mode". HP typically uses a lis3 accelerometer for HDD
fall protection. What I believe is happening here is that on newer
HP devices, which only contain a SDD, the BIOS is leaving the lis3 device
powered-down since it is not used for HDD fall protection.

Note that the lis3_3dc_rates array initializer only specifies 10 values,
which matches the datasheet. So it also contains 6 zero values at the end.

Replace the WARN with a normal check, which treats an odr index of 0
as power-down and uses a normal dev_err() to report the error in case
odr index point past the initialized part of the array.

BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=785814
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1817027
BugLink: https://bugs.centos.org/view.php?id=10720
Fixes: 1510dd5954be ("lis3lv02d: avoid divide by zero due to unchecked")
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/misc/lis3lv02d/lis3lv02d.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index dd65cedf3b12..9d14bf444481 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -208,7 +208,7 @@ static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
 static int lis3_3dlh_rates[4] = {50, 100, 400, 1000};
 
 /* ODR is Output Data Rate */
-static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
+static int lis3lv02d_get_odr_index(struct lis3lv02d *lis3)
 {
 	u8 ctrl;
 	int shift;
@@ -216,15 +216,23 @@ static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
 	lis3->read(lis3, CTRL_REG1, &ctrl);
 	ctrl &= lis3->odr_mask;
 	shift = ffs(lis3->odr_mask) - 1;
-	return lis3->odrs[(ctrl >> shift)];
+	return (ctrl >> shift);
 }
 
 static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
 {
-	int div = lis3lv02d_get_odr(lis3);
+	int odr_idx = lis3lv02d_get_odr_index(lis3);
+	int div = lis3->odrs[odr_idx];
 
-	if (WARN_ONCE(div == 0, "device returned spurious data"))
+	if (div == 0) {
+		if (odr_idx == 0) {
+			/* Power-down mode, not sampling no need to sleep */
+			return 0;
+		}
+
+		dev_err(&lis3->pdev->dev, "Error unknown odrs-index: %d\n", odr_idx);
 		return -ENXIO;
+	}
 
 	/* LIS3 power on delay is quite long */
 	msleep(lis3->pwron_delay / div);
@@ -816,9 +824,12 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
 	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
+	int odr_idx;
 
 	lis3lv02d_sysfs_poweron(lis3);
-	return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3));
+
+	odr_idx = lis3lv02d_get_odr_index(lis3);
+	return sprintf(buf, "%d\n", lis3->odrs[odr_idx]);
 }
 
 static ssize_t lis3lv02d_rate_set(struct device *dev,
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/3] misc: lis3lv02d: Change lis3lv02d_init_device() return value for unknown sensors to -ENODEV
  2021-02-17 10:24 [PATCH 1/3] misc: lis3lv02d: Fix false-positive WARN on various HP models Hans de Goede
@ 2021-02-17 10:25 ` Hans de Goede
  2021-02-17 10:25 ` [PATCH 3/3] misc: lis3lv02d: Do not log an error when kmalloc fails Hans de Goede
  1 sibling, 0 replies; 3+ messages in thread
From: Hans de Goede @ 2021-02-17 10:25 UTC (permalink / raw)
  To: Eric Piel, Arnd Bergmann, Greg Kroah-Hartman; +Cc: Hans de Goede, linux-kernel

Modern HP laptops do not necessarily actually contain a lis3lv02d
sensor, yet they still define a HPQ6007 device in there ACPI tables.

This leads to the following messages being logged in dmesg:

[   17.376342] hp_accel: laptop model unknown, using default axes configuration
[   17.399766] lis3lv02d: unknown sensor type 0x0
[   17.399804] hp_accel: probe of HPQ6007:00 failed with error -22

The third message is unnecessary and does not provide any useful info,
change the return value for unknown sensors to -ENODEV. This is the
proper return value to indicate that the driver will not be handling the
device and it silences the pr_warn printing the third message.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199715
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Note this does not resolve the bko 199715 bug, it merely silences the
message which was used in the Summary when the bug was first filed.
That bug really is about the actual accelerometer, which uses the AMD
sensor fusion hub, not working.
---
 drivers/misc/lis3lv02d/lis3lv02d.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 9d14bf444481..22dacfaad02f 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -1173,7 +1173,7 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
 		break;
 	default:
 		pr_err("unknown sensor type 0x%X\n", lis3->whoami);
-		return -EINVAL;
+		return -ENODEV;
 	}
 
 	lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 3/3] misc: lis3lv02d: Do not log an error when kmalloc fails
  2021-02-17 10:24 [PATCH 1/3] misc: lis3lv02d: Fix false-positive WARN on various HP models Hans de Goede
  2021-02-17 10:25 ` [PATCH 2/3] misc: lis3lv02d: Change lis3lv02d_init_device() return value for unknown sensors to -ENODEV Hans de Goede
@ 2021-02-17 10:25 ` Hans de Goede
  1 sibling, 0 replies; 3+ messages in thread
From: Hans de Goede @ 2021-02-17 10:25 UTC (permalink / raw)
  To: Eric Piel, Arnd Bergmann, Greg Kroah-Hartman; +Cc: Hans de Goede, linux-kernel

Logging an error when kmalloc fails is not necessary (and in general
should be avoided) because the malloc failure will already complain
loudly itself.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/misc/lis3lv02d/lis3lv02d.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 22dacfaad02f..70c5bb1e6f49 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -1179,10 +1179,8 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
 	lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
 				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
 
-	if (lis3->reg_cache == NULL) {
-		printk(KERN_ERR DRIVER_NAME "out of memory\n");
+	if (lis3->reg_cache == NULL)
 		return -ENOMEM;
-	}
 
 	mutex_init(&lis3->mutex);
 	atomic_set(&lis3->wake_thread, 0);
-- 
2.30.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-02-17 10:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-17 10:24 [PATCH 1/3] misc: lis3lv02d: Fix false-positive WARN on various HP models Hans de Goede
2021-02-17 10:25 ` [PATCH 2/3] misc: lis3lv02d: Change lis3lv02d_init_device() return value for unknown sensors to -ENODEV Hans de Goede
2021-02-17 10:25 ` [PATCH 3/3] misc: lis3lv02d: Do not log an error when kmalloc fails Hans de Goede

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).