lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 16 Nov 2011 00:43:16 +0100
From:	Maciej Szmigiero <mhej@...pl>
To:	Evgeniy Polyakov <zbr@...emap.net>,
	Andrew Morton <akpm@...ux-foundation.org>,
	Christian Glindkamp <christian.glindkamp@...kit.de>,
	linux-kernel@...r.kernel.org
Subject: [PATCH][W1]w1_therm: release the bus during conversion on externally
 powered devices

w1_therm devices can either be bus powered or externally powered.

When device is bus powered during temperature conversion the bus
have to be left high to provide necessary power. Some masters also allow
strong power-up to be enabled in this case.
Naturally, no communication over bus can occur during that time.

However, if device has external power then there is no such restriction,
and host can talk to other devices during temperature conversion.

There is command which allows us to check how device is powered,
this patch uses it to release the bus on externally w1_therm powered devices
during temperature conversion.

Also, this changes uninterruptible sleeps there into interruptible ones to
avoid long uninterruptible sleep if w1 subsystem happens to grab bus for
scan during w1_therm_read().

Signed-off-by: Maciej Szmigiero <mhej@...pl>

diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index a1ef9b5..ff29ae7 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -175,11 +175,13 @@ static ssize_t w1_therm_read(struct device *device,
 {
 	struct w1_slave *sl = dev_to_w1_slave(device);
 	struct w1_master *dev = sl->master;
-	u8 rom[9], crc, verdict;
+	u8 rom[9], crc, verdict, external_power;
 	int i, max_trying = 10;
 	ssize_t c = PAGE_SIZE;
 
-	mutex_lock(&dev->mutex);
+	i = mutex_lock_interruptible(&dev->mutex);
+	if (i != 0)
+		return i;
 
 	memset(rom, 0, sizeof(rom));
 
@@ -190,13 +192,37 @@ static ssize_t w1_therm_read(struct device *device,
 		if (!w1_reset_select_slave(sl)) {
 			int count = 0;
 			unsigned int tm = 750;
+			unsigned long sleep_rem;
+
+			w1_write_8(dev, W1_READ_PSUPPLY);
+			external_power = w1_read_8(dev);
+
+			if (w1_reset_select_slave(sl))
+				continue;
 
 			/* 750ms strong pullup (or delay) after the convert */
-			if (w1_strong_pullup)
+			if (!external_power && w1_strong_pullup)
 				w1_next_pullup(dev, tm);
+
 			w1_write_8(dev, W1_CONVERT_TEMP);
-			if (!w1_strong_pullup)
-				msleep(tm);
+
+			if (external_power) {
+				mutex_unlock(&dev->mutex);
+
+				sleep_rem = msleep_interruptible(tm);
+				if (sleep_rem != 0)
+					return -EINTR;
+
+				i = mutex_lock_interruptible(&dev->mutex);
+				if (i != 0)
+					return i;
+			} else if (!w1_strong_pullup) {
+				sleep_rem = msleep_interruptible(tm);
+				if (sleep_rem != 0) {
+					mutex_unlock(&dev->mutex);
+					return -EINTR;
+				}
+			}
 
 			if (!w1_reset_select_slave(sl)) {
 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ