All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] IAD Register is yet readable trough iad sys file. Fix snprintf (%u for unsigned, count for max size).
@ 2018-09-10 17:36 Julien Folly
  2018-09-10 17:56 ` Greg KH
  0 siblings, 1 reply; 3+ messages in thread
From: Julien Folly @ 2018-09-10 17:36 UTC (permalink / raw)
  To: linux-kernel; +Cc: greg, manio


Signed-off-by: Julien Folly <julien.folly@gmail.com>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
---
  drivers/w1/slaves/w1_ds2438.c | 66 ++++++++++++++++++++++++++++++++++---------
  1 file changed, 52 insertions(+), 14 deletions(-)

diff --git a/drivers/w1/slaves/w1_ds2438.c b/drivers/w1/slaves/w1_ds2438.c
index bf641a1..7c4e33d 100644
--- a/drivers/w1/slaves/w1_ds2438.c
+++ b/drivers/w1/slaves/w1_ds2438.c
@@ -186,8 +186,8 @@ static int w1_ds2438_change_config_bit(struct w1_slave *sl, u8 mask, u8 value)
  	return -1;
  }
  
-static uint16_t w1_ds2438_get_voltage(struct w1_slave *sl,
-				      int adc_input, uint16_t *voltage)
+static int w1_ds2438_get_voltage(struct w1_slave *sl,
+				 int adc_input, uint16_t *voltage)
  {
  	unsigned int retries = W1_DS2438_RETRIES;
  	u8 w1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/];
@@ -235,6 +235,25 @@ static uint16_t w1_ds2438_get_voltage(struct w1_slave *sl,
  	return ret;
  }
  
+static int w1_ds2438_get_current(struct w1_slave *sl, int16_t *voltage)
+{
+	u8 w1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/];
+	int ret;
+
+	mutex_lock(&sl->master->bus_mutex);
+
+	if (w1_ds2438_get_page(sl, 0, w1_buf) == 0) {
+		/* The voltage measured across current sense resistor RSENS. */
+		*voltage = (((int16_t) w1_buf[DS2438_CURRENT_MSB]) << 8) | ((int16_t) w1_buf[DS2438_CURRENT_LSB]);
+		ret = 0;
+	} else
+		ret = -1;
+
+	mutex_unlock(&sl->master->bus_mutex);
+
+	return ret;
+}
+
  static ssize_t iad_write(struct file *filp, struct kobject *kobj,
  			 struct bin_attribute *bin_attr, char *buf,
  			 loff_t off, size_t count)
@@ -257,6 +276,27 @@ static ssize_t iad_write(struct file *filp, struct kobject *kobj,
  	return ret;
  }
  
+static ssize_t iad_read(struct file *filp, struct kobject *kobj,
+			struct bin_attribute *bin_attr, char *buf,
+			loff_t off, size_t count)
+{
+	struct w1_slave *sl = kobj_to_w1_slave(kobj);
+	int ret;
+	int16_t voltage;
+
+	if (off != 0)
+		return 0;
+	if (!buf)
+		return -EINVAL;
+
+	if (w1_ds2438_get_current(sl, &voltage) == 0) {
+		ret = snprintf(buf, count, "%i\n", voltage);
+	} else
+		ret = -EIO;
+
+	return ret;
+}
+
  static ssize_t page0_read(struct file *filp, struct kobject *kobj,
  			  struct bin_attribute *bin_attr, char *buf,
  			  loff_t off, size_t count)
@@ -272,9 +312,13 @@ static ssize_t page0_read(struct file *filp, struct kobject *kobj,
  
  	mutex_lock(&sl->master->bus_mutex);
  
+	/* Read no more than page0 size */
+	if (count > DS2438_PAGE_SIZE)
+		count = DS2438_PAGE_SIZE;
+
  	if (w1_ds2438_get_page(sl, 0, w1_buf) == 0) {
-		memcpy(buf, &w1_buf, DS2438_PAGE_SIZE);
-		ret = DS2438_PAGE_SIZE;
+		memcpy(buf, &w1_buf, count);
+		ret = count;
  	} else
  		ret = -EIO;
  
@@ -289,7 +333,6 @@ static ssize_t temperature_read(struct file *filp, struct kobject *kobj,
  {
  	struct w1_slave *sl = kobj_to_w1_slave(kobj);
  	int ret;
-	ssize_t c = PAGE_SIZE;
  	int16_t temp;
  
  	if (off != 0)
@@ -298,8 +341,7 @@ static ssize_t temperature_read(struct file *filp, struct kobject *kobj,
  		return -EINVAL;
  
  	if (w1_ds2438_get_temperature(sl, &temp) == 0) {
-		c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", temp);
-		ret = PAGE_SIZE - c;
+		ret = snprintf(buf, count, "%i\n", temp);
  	} else
  		ret = -EIO;
  
@@ -312,7 +354,6 @@ static ssize_t vad_read(struct file *filp, struct kobject *kobj,
  {
  	struct w1_slave *sl = kobj_to_w1_slave(kobj);
  	int ret;
-	ssize_t c = PAGE_SIZE;
  	uint16_t voltage;
  
  	if (off != 0)
@@ -321,8 +362,7 @@ static ssize_t vad_read(struct file *filp, struct kobject *kobj,
  		return -EINVAL;
  
  	if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VAD, &voltage) == 0) {
-		c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", voltage);
-		ret = PAGE_SIZE - c;
+		ret = snprintf(buf, count, "%u\n", voltage);
  	} else
  		ret = -EIO;
  
@@ -335,7 +375,6 @@ static ssize_t vdd_read(struct file *filp, struct kobject *kobj,
  {
  	struct w1_slave *sl = kobj_to_w1_slave(kobj);
  	int ret;
-	ssize_t c = PAGE_SIZE;
  	uint16_t voltage;
  
  	if (off != 0)
@@ -344,15 +383,14 @@ static ssize_t vdd_read(struct file *filp, struct kobject *kobj,
  		return -EINVAL;
  
  	if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VDD, &voltage) == 0) {
-		c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", voltage);
-		ret = PAGE_SIZE - c;
+		ret = snprintf(buf, count, "%u\n", voltage);
  	} else
  		ret = -EIO;
  
  	return ret;
  }
  
-static BIN_ATTR(iad, S_IRUGO | S_IWUSR | S_IWGRP, NULL, iad_write, 1);
+static BIN_ATTR(iad, S_IRUGO | S_IWUSR | S_IWGRP, iad_read, iad_write, 0);
  static BIN_ATTR_RO(page0, DS2438_PAGE_SIZE);
  static BIN_ATTR_RO(temperature, 0/* real length varies */);
  static BIN_ATTR_RO(vad, 0/* real length varies */);
-- 
2.7.4


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

* Re: [PATCH] IAD Register is yet readable trough iad sys file. Fix snprintf (%u for unsigned, count for max size).
  2018-09-10 17:36 [PATCH] IAD Register is yet readable trough iad sys file. Fix snprintf (%u for unsigned, count for max size) Julien Folly
@ 2018-09-10 17:56 ` Greg KH
  0 siblings, 0 replies; 3+ messages in thread
From: Greg KH @ 2018-09-10 17:56 UTC (permalink / raw)
  To: Julien Folly; +Cc: linux-kernel, manio

On Mon, Sep 10, 2018 at 07:36:51PM +0200, Julien Folly wrote:
> 
> Signed-off-by: Julien Folly <julien.folly@gmail.com>
> Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
> ---
>  drivers/w1/slaves/w1_ds2438.c | 66 ++++++++++++++++++++++++++++++++++---------
>  1 file changed, 52 insertions(+), 14 deletions(-)

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- You did not specify a description of why the patch is needed, or
  possibly, any description at all, in the email body.  Please read the
  section entitled "The canonical patch format" in the kernel file,
  Documentation/SubmittingPatches for what is needed in order to
  properly describe the change.

- You did not write a descriptive Subject: for the patch, allowing Greg,
  and everyone else, to know what this patch is all about.  Please read
  the section entitled "The canonical patch format" in the kernel file,
  Documentation/SubmittingPatches for what a proper Subject: line should
  look like.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot

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

* [PATCH] IAD Register is yet readable trough iad sys file. Fix snprintf (%u for unsigned, count for max size).
       [not found] <af443df9-b919-24ee-70ac-dbc80566f787@gmail.com>
@ 2018-10-09 17:47 ` Julien Folly
  0 siblings, 0 replies; 3+ messages in thread
From: Julien Folly @ 2018-10-09 17:47 UTC (permalink / raw)
  To: linux-kernel; +Cc: greg, manio

IAD Register is yet readable trough the "iad" sys file.

A write to the "iad" sys file enables or disables the current
measurement, but it was not possible to get the measured value by
reading it.
Fix: %u in snprintf for unsigned values (vdd and vad)
Fix: Avoid possibles overflows (Usage of the 'count' variables)

Signed-off-by: Julien Folly <julien.folly@gmail.com>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
---
  drivers/w1/slaves/w1_ds2438.c | 66 ++++++++++++++++++++++++++++++++++---------
  1 file changed, 52 insertions(+), 14 deletions(-)

diff --git a/drivers/w1/slaves/w1_ds2438.c b/drivers/w1/slaves/w1_ds2438.c
index bf641a1..7c4e33d 100644
--- a/drivers/w1/slaves/w1_ds2438.c
+++ b/drivers/w1/slaves/w1_ds2438.c
@@ -186,8 +186,8 @@ static int w1_ds2438_change_config_bit(struct w1_slave *sl, u8 mask, u8 value)
  	return -1;
  }
  
-static uint16_t w1_ds2438_get_voltage(struct w1_slave *sl,
-				      int adc_input, uint16_t *voltage)
+static int w1_ds2438_get_voltage(struct w1_slave *sl,
+				 int adc_input, uint16_t *voltage)
  {
  	unsigned int retries = W1_DS2438_RETRIES;
  	u8 w1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/];
@@ -235,6 +235,25 @@ static uint16_t w1_ds2438_get_voltage(struct w1_slave *sl,
  	return ret;
  }
  
+static int w1_ds2438_get_current(struct w1_slave *sl, int16_t *voltage)
+{
+	u8 w1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/];
+	int ret;
+
+	mutex_lock(&sl->master->bus_mutex);
+
+	if (w1_ds2438_get_page(sl, 0, w1_buf) == 0) {
+		/* The voltage measured across current sense resistor RSENS. */
+		*voltage = (((int16_t) w1_buf[DS2438_CURRENT_MSB]) << 8) | ((int16_t) w1_buf[DS2438_CURRENT_LSB]);
+		ret = 0;
+	} else
+		ret = -1;
+
+	mutex_unlock(&sl->master->bus_mutex);
+
+	return ret;
+}
+
  static ssize_t iad_write(struct file *filp, struct kobject *kobj,
  			 struct bin_attribute *bin_attr, char *buf,
  			 loff_t off, size_t count)
@@ -257,6 +276,27 @@ static ssize_t iad_write(struct file *filp, struct kobject *kobj,
  	return ret;
  }
  
+static ssize_t iad_read(struct file *filp, struct kobject *kobj,
+			struct bin_attribute *bin_attr, char *buf,
+			loff_t off, size_t count)
+{
+	struct w1_slave *sl = kobj_to_w1_slave(kobj);
+	int ret;
+	int16_t voltage;
+
+	if (off != 0)
+		return 0;
+	if (!buf)
+		return -EINVAL;
+
+	if (w1_ds2438_get_current(sl, &voltage) == 0) {
+		ret = snprintf(buf, count, "%i\n", voltage);
+	} else
+		ret = -EIO;
+
+	return ret;
+}
+
  static ssize_t page0_read(struct file *filp, struct kobject *kobj,
  			  struct bin_attribute *bin_attr, char *buf,
  			  loff_t off, size_t count)
@@ -272,9 +312,13 @@ static ssize_t page0_read(struct file *filp, struct kobject *kobj,
  
  	mutex_lock(&sl->master->bus_mutex);
  
+	/* Read no more than page0 size */
+	if (count > DS2438_PAGE_SIZE)
+		count = DS2438_PAGE_SIZE;
+
  	if (w1_ds2438_get_page(sl, 0, w1_buf) == 0) {
-		memcpy(buf, &w1_buf, DS2438_PAGE_SIZE);
-		ret = DS2438_PAGE_SIZE;
+		memcpy(buf, &w1_buf, count);
+		ret = count;
  	} else
  		ret = -EIO;
  
@@ -289,7 +333,6 @@ static ssize_t temperature_read(struct file *filp, struct kobject *kobj,
  {
  	struct w1_slave *sl = kobj_to_w1_slave(kobj);
  	int ret;
-	ssize_t c = PAGE_SIZE;
  	int16_t temp;
  
  	if (off != 0)
@@ -298,8 +341,7 @@ static ssize_t temperature_read(struct file *filp, struct kobject *kobj,
  		return -EINVAL;
  
  	if (w1_ds2438_get_temperature(sl, &temp) == 0) {
-		c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", temp);
-		ret = PAGE_SIZE - c;
+		ret = snprintf(buf, count, "%i\n", temp);
  	} else
  		ret = -EIO;
  
@@ -312,7 +354,6 @@ static ssize_t vad_read(struct file *filp, struct kobject *kobj,
  {
  	struct w1_slave *sl = kobj_to_w1_slave(kobj);
  	int ret;
-	ssize_t c = PAGE_SIZE;
  	uint16_t voltage;
  
  	if (off != 0)
@@ -321,8 +362,7 @@ static ssize_t vad_read(struct file *filp, struct kobject *kobj,
  		return -EINVAL;
  
  	if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VAD, &voltage) == 0) {
-		c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", voltage);
-		ret = PAGE_SIZE - c;
+		ret = snprintf(buf, count, "%u\n", voltage);
  	} else
  		ret = -EIO;
  
@@ -335,7 +375,6 @@ static ssize_t vdd_read(struct file *filp, struct kobject *kobj,
  {
  	struct w1_slave *sl = kobj_to_w1_slave(kobj);
  	int ret;
-	ssize_t c = PAGE_SIZE;
  	uint16_t voltage;
  
  	if (off != 0)
@@ -344,15 +383,14 @@ static ssize_t vdd_read(struct file *filp, struct kobject *kobj,
  		return -EINVAL;
  
  	if (w1_ds2438_get_voltage(sl, DS2438_ADC_INPUT_VDD, &voltage) == 0) {
-		c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", voltage);
-		ret = PAGE_SIZE - c;
+		ret = snprintf(buf, count, "%u\n", voltage);
  	} else
  		ret = -EIO;
  
  	return ret;
  }
  
-static BIN_ATTR(iad, S_IRUGO | S_IWUSR | S_IWGRP, NULL, iad_write, 1);
+static BIN_ATTR(iad, S_IRUGO | S_IWUSR | S_IWGRP, iad_read, iad_write, 0);
  static BIN_ATTR_RO(page0, DS2438_PAGE_SIZE);
  static BIN_ATTR_RO(temperature, 0/* real length varies */);
  static BIN_ATTR_RO(vad, 0/* real length varies */);
-- 
2.7.4


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

end of thread, other threads:[~2018-10-09 17:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-10 17:36 [PATCH] IAD Register is yet readable trough iad sys file. Fix snprintf (%u for unsigned, count for max size) Julien Folly
2018-09-10 17:56 ` Greg KH
     [not found] <af443df9-b919-24ee-70ac-dbc80566f787@gmail.com>
2018-10-09 17:47 ` Julien Folly

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.