RE: [PATCH] Input: elan_i2c - Prevent breaking of FW updating from unexpected signal

From: 廖崇榮
Date: Wed May 24 2017 - 04:53:07 EST


Hi Dmitry

-----Original Message-----
From: Dmitry Torokhov [mailto:dmitry.torokhov@xxxxxxxxx]
Sent: Wednesday, May 24, 2017 5:14 AM
To: KT Liao
Cc: linux-kernel@xxxxxxxxxxxxxxx; linux-input@xxxxxxxxxxxxxxx;
phoenix@xxxxxxxxxx
Subject: Re: [PATCH] Input: elan_i2c - Prevent breaking of FW updating from
unexpected signal

Hi KT,

On Tue, May 23, 2017 at 10:32:02PM +0800, KT Liao wrote:
> Use wait_for_completion_timeout to prevent breaking of FW updating from
unexpected signal
>
> Signed-off-by: KT Liao <kt.liao@xxxxxxxxxx>
> ---
> drivers/input/mouse/elan_i2c_i2c.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/input/mouse/elan_i2c_i2c.c
b/drivers/input/mouse/elan_i2c_i2c.c
> index 3be75c6e..34356c7 100644
> --- a/drivers/input/mouse/elan_i2c_i2c.c
> +++ b/drivers/input/mouse/elan_i2c_i2c.c
> @@ -619,7 +619,7 @@ static int elan_i2c_finish_fw_update(struct i2c_client
*client,
>
> error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD,
ETP_I2C_RESET);
> if (!error)
> - ret = wait_for_completion_interruptible_timeout(completion,
> + ret = wait_for_completion_timeout(completion,
>
msecs_to_jiffies(300));
> disable_irq(client->irq);
>
> --
> 2.7.4
>

wait_for_completion_timeout(), unlike
wait_for_completion_interruptible_timeout() returns unsigned long, so
the code below checking if 'ret' is negative, is no longer needed. How
about the version of the patch below?
[KT] : Thanks, it's ok. We have tested it on some Chrome system.
--
Dmitry


Input: elan_i2c - ignore signals when finishing updating firmware

From: KT Liao <kt.liao@xxxxxxxxxx>

Use wait_for_completion_timeout() instead of
wait_for_completion_interruptible_timeout() to avoid stray signals ruining
firmware update. Our timeout is only 300 msec so we are fine simply letting
it expire in case device misbehaves.

Signed-off-by: KT Liao <kt.liao@xxxxxxxxxx>
Patchwork-Id: 9742857
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
---
drivers/input/mouse/elan_i2c_i2c.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/input/mouse/elan_i2c_i2c.c
b/drivers/input/mouse/elan_i2c_i2c.c
index 3be75c6e8090..278832047075 100644
--- a/drivers/input/mouse/elan_i2c_i2c.c
+++ b/drivers/input/mouse/elan_i2c_i2c.c
@@ -609,7 +609,6 @@ static int elan_i2c_finish_fw_update(struct i2c_client
*client,
struct completion *completion)
{
struct device *dev = &client->dev;
- long ret;
int error;
int len;
u8 buffer[ETP_I2C_INF_LENGTH];
@@ -618,23 +617,19 @@ static int elan_i2c_finish_fw_update(struct i2c_client
*client,
enable_irq(client->irq);

error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD,
ETP_I2C_RESET);
- if (!error)
- ret = wait_for_completion_interruptible_timeout(completion,
- msecs_to_jiffies(300
));
- disable_irq(client->irq);
-
if (error) {
dev_err(dev, "device reset failed: %d\n", error);
- return error;
- } else if (ret == 0) {
+ } else if (!wait_for_completion_timeout(completion,
+ msecs_to_jiffies(300))) {
dev_err(dev, "timeout waiting for device reset\n");
- return -ETIMEDOUT;
- } else if (ret < 0) {
- error = ret;
- dev_err(dev, "error waiting for device reset: %d\n", error);
- return error;
+ error = -ETIMEDOUT;
}

+ disable_irq(client->irq);
+
+ if (error)
+ return error;
+
len = i2c_master_recv(client, buffer, ETP_I2C_INF_LENGTH);
if (len != ETP_I2C_INF_LENGTH) {
error = len < 0 ? len : -EIO;