Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp1423479img; Tue, 19 Mar 2019 07:22:43 -0700 (PDT) X-Google-Smtp-Source: APXvYqyHDggL+GRDUeYqktn62QGE/+ck2DU/6C/gWCmTcvDWban1j+fzu14cLDm05R8WzYI+9TSH X-Received: by 2002:a65:5c4b:: with SMTP id v11mr2053651pgr.411.1553005363284; Tue, 19 Mar 2019 07:22:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553005363; cv=none; d=google.com; s=arc-20160816; b=l4DXGKXuZRPG85uymkyNVkByTb0pcBV5DnmGtUDh+rIAtYcfPiE/Bb2yJHaSHDLEl/ 93+OEFHErTMPH/KUj77FCug1IPJ+J3LMb2d2441tFQKEcu9eZGKDfyhRq0eSp7ytYrqp l1l/Z33Uq0tHLGT4mGI54MitrDGf+vewCXkw8rZLUQZwmntVKssYtJYXWJ5/OTEQm+2G iqlCVz2Y12+S7SAvMjoaIDRQuiCPm1LpzzmbLaYUXTyUYBwVPU0O/7IIMKM237HnHDhy /1yEoLTnFfHLMve+5FaJbX1PPLyE1Vz6OaYYj+/64kZWkRpSP8BT2Mv9V/lmbFbpLkHQ Zfyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:references:message-id :content-transfer-encoding:cc:date:in-reply-to:from:subject :mime-version:dkim-signature; bh=Gnr9sn2PbmUnDDxyv0YS0Zaj+dimt19m4HxDy9V5ZSw=; b=VWK9mm398ez9dn+I/2mOAIpg5YF1DoClY5VbFlqK9F14bVWES1UdgsaL8+WMWBC/4f BDaHPTaeQlg9+ylSSIrTwvKO2XsCwI+29AcRgYyow1Q2KjXFhhWSXvq0WDr++sOLljTJ gQ6vQgizrBs9VaDv0Hzp7YM8oJDKJG06I8yLbPNnOLNfNi4raW2I39Z5yS5aRfjnQB33 5CQO72s6cB2/U7bqSuktJwZ74re9yEGysHpiszPocQHyWIgcowi/xNGFpL2NVSAV+etf uN3fe7b9brO1L48b9n5WcJhfMVJ78DmkCLU0xda1LjnEZ1GuDVnBED3G3qO2iSZpvJEX w/MQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=A58bLwx8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g8si12203774plt.141.2019.03.19.07.22.27; Tue, 19 Mar 2019 07:22:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=A58bLwx8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726812AbfCSOVg (ORCPT + 99 others); Tue, 19 Mar 2019 10:21:36 -0400 Received: from mail-qt1-f196.google.com ([209.85.160.196]:39621 "EHLO mail-qt1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726661AbfCSOVf (ORCPT ); Tue, 19 Mar 2019 10:21:35 -0400 Received: by mail-qt1-f196.google.com with SMTP id t28so22292564qte.6 for ; Tue, 19 Mar 2019 07:21:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=Gnr9sn2PbmUnDDxyv0YS0Zaj+dimt19m4HxDy9V5ZSw=; b=A58bLwx8HXhP6CLli+cSbfoaBD/E07xnYLzPI88Rq1/vfcRxuoobJNvJVQ903dMhaC 31mvAvcSNKA/3Ne35omQebVZhii0DDMt8dX+riHEpWC0rxH9tWrmI8KnE3TKVXW4FbHv UIhYOiA7CHRuUxDDPfauVCXutiqRojGpOyXH8BemAMj7tsWt7OYQV+MUod1+YqtgVLz6 94okkvhE5ZmU6x+yFu2WoyQpLPIjXHkQgun9h3IYH4aI5sAJ2GD+KI3YbZzG5rDxtDNb qaeTTLR5S9VICrLPrn5fybqcfW38DIQ18riz63SPw0Z/4E7kNidl/40SuTwzjPHVBmJL f5NQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=Gnr9sn2PbmUnDDxyv0YS0Zaj+dimt19m4HxDy9V5ZSw=; b=ActM7yyodmOYf6Lp+K6ewEvIfg2yrbNQCkH/d5bSj9HCiLP9FL2gobjRMJCmKKBxko 4GLaep3isDGv3l93HwERZGIj6XvTF1YReyT3Ye51oZklDsAEYWk1DZAkRCKm4rkpyyS0 geNcbsDJtNcGYjtPeG3WcxHzJySOW7eGMaPsxB/mQ5hAfXVDEYeb4BY3Z/T8n27WFrQ3 uhcJ43L2phV6uWOaVHW0zmX4LIZlpa9UPNz/5C02VYhFwo0EhJWxVuYTqit4uqRt2nQQ Px7q3tgffODk5yPHXtUsRibtBzK6SI1wmfSxqXPHDneOxhW+atlpdp+UGJAXV1VU9DUg I2Fw== X-Gm-Message-State: APjAAAU1TNZE+/1UjUONnw7TCZKXUR2iaLS8x564j2+OXbWz6YZUKehm ENc+Uy2RmcojmsguiTMkNWmWxJd7 X-Received: by 2002:ac8:3585:: with SMTP id k5mr2182473qtb.55.1553005294155; Tue, 19 Mar 2019 07:21:34 -0700 (PDT) Received: from jfdmac.sonatest.net (ipagstaticip-d73c7528-4de5-0861-800b-03d8b15e3869.sdsl.bell.ca. [174.94.156.236]) by smtp.gmail.com with ESMTPSA id 92sm7036854qtc.97.2019.03.19.07.21.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Mar 2019 07:21:33 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.2 \(3445.102.3\)) Subject: Re: [PATCH 1/2] w1: ds2408: add a missing reset when retrying in output_write() From: Jean-Francois Dagenais In-Reply-To: <20190318092737.8170-2-manio@skyboo.net> Date: Tue, 19 Mar 2019 10:21:32 -0400 Cc: linux-kernel@vger.kernel.org, Evgeniy Polyakov , Greg Kroah-Hartman Content-Transfer-Encoding: quoted-printable Message-Id: References: <20190318092737.8170-1-manio@skyboo.net> <20190318092737.8170-2-manio@skyboo.net> To: Mariusz Bialonczyk X-Mailer: Apple Mail (2.3445.102.3) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > On Mar 18, 2019, at 05:27, Mariusz Bialonczyk = wrote: >=20 > When we have success in 'Channel Access Write' but reading back the = latch > state has failed, then the code continues but without doing a proper > slave reset. This was leading to protocol errors as the slave treats > the next 'Channel Access Write' as the continuation of previous = command. >=20 > This commit is fixing this, and because we have to reset no matter if > the actual write or the readback checking is failing then the = resetting > is done on the beginning of the loop. >=20 > Signed-off-by: Mariusz Bialonczyk > Cc: Jean-Francois Dagenais > --- > drivers/w1/slaves/w1_ds2408.c | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) >=20 > diff --git a/drivers/w1/slaves/w1_ds2408.c = b/drivers/w1/slaves/w1_ds2408.c > index b535d5ec35b6..562ee2d861e8 100644 > --- a/drivers/w1/slaves/w1_ds2408.c > +++ b/drivers/w1/slaves/w1_ds2408.c > @@ -158,6 +158,13 @@ static ssize_t output_write(struct file *filp, = struct kobject *kobj, > goto error; >=20 > while (retries--) { > + /* do a reset/resume on every new retry call > + except the first one */ > + if (retries < W1_F29_RETRIES - 1) { > + if (w1_reset_resume_command(sl->master)) > + goto error; > + } > + The case being solved here is strictly restricted to the CONFIG_W1_SLAVE_DS2408_READBACK case and should be confined to this = macro being defined. I think my original code here is to blame. Although I = appreciate what you are trying to fix and that this does it, I don't really appreciate = the resulting style as it puts the improbable case of the retry in the = forefront of the loop using a non-obvious condition. This adds burden to the reader. Since this is an error handling case, it = should like like so and be handled lower in the loop. May I suggest a cleaned = up version my original klunky code with your fix in it (Note: this is = untested, it compiles on arm64, that's all): drivers/w1/slaves/w1_ds2408.c | 78 = ++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/drivers/w1/slaves/w1_ds2408.c = b/drivers/w1/slaves/w1_ds2408.c index b535d5ec35b6..bf308660f6ae 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -138,6 +138,34 @@ static ssize_t status_control_read(struct file = *filp, struct kobject *kobj, W1_F29_REG_CONTROL_AND_STATUS, buf); } =20 +#ifdef CONFIG_W1_SLAVE_DS2408_READBACK +static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) +{ + u8 w1_buf[3]; + /* here the master could read another byte which + would be the PIO reg (the actual pin logic state) + since in this driver we don't know which pins are + in and outs, there's no value to read the state and + compare. with (*buf) so end this command abruptly: */ + if (w1_reset_resume_command(sl->master)) + return false; + /* go read back the output latches */ + /* (the direct effect of the write access) */ + w1_buf[0] =3D W1_F29_FUNC_READ_PIO_REGS; + w1_buf[1] =3D W1_F29_REG_OUTPUT_LATCH_STATE; + w1_buf[2] =3D 0; + w1_write_block(sl->master, w1_buf, 3); + + /* read the result of the READ_PIO_REGS command */ + return w1_read_8(sl->master) =3D=3D expected; +} +#else +static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) +{ + return true; +} +#endif + static ssize_t output_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -146,6 +174,7 @@ static ssize_t output_write(struct file *filp, = struct kobject *kobj, u8 w1_buf[3]; u8 readBack; unsigned int retries =3D W1_F29_RETRIES; + ssize_t bytes_written =3D -EIO; =20 if (count !=3D 1 || off !=3D 0) return -EFAULT; @@ -155,9 +184,9 @@ static ssize_t output_write(struct file *filp, = struct kobject *kobj, dev_dbg(&sl->dev, "mutex locked"); =20 if (w1_reset_select_slave(sl)) - goto error; + goto out; =20 - while (retries--) { + do { w1_buf[0] =3D W1_F29_FUNC_CHANN_ACCESS_WRITE; w1_buf[1] =3D *buf; w1_buf[2] =3D ~(*buf); @@ -165,44 +194,23 @@ static ssize_t output_write(struct file *filp, = struct kobject *kobj, =20 readBack =3D w1_read_8(sl->master); =20 - if (readBack !=3D W1_F29_SUCCESS_CONFIRM_BYTE) { - if (w1_reset_resume_command(sl->master)) - goto error; - /* try again, the slave is ready for a command = */ - continue; + if (readBack =3D=3D W1_F29_SUCCESS_CONFIRM_BYTE && + optional_read_back_valid(sl, *buf)) { + bytes_written =3D 1; + goto out; } =20 -#ifdef CONFIG_W1_SLAVE_DS2408_READBACK - /* here the master could read another byte which - would be the PIO reg (the actual pin logic state) - since in this driver we don't know which pins are - in and outs, there's no value to read the state and - compare. with (*buf) so end this command abruptly: */ if (w1_reset_resume_command(sl->master)) - goto error; - - /* go read back the output latches */ - /* (the direct effect of the write above) */ - w1_buf[0] =3D W1_F29_FUNC_READ_PIO_REGS; - w1_buf[1] =3D W1_F29_REG_OUTPUT_LATCH_STATE; - w1_buf[2] =3D 0; - w1_write_block(sl->master, w1_buf, 3); - /* read the result of the READ_PIO_REGS command */ - if (w1_read_8(sl->master) =3D=3D *buf) -#endif - { - /* success! */ - mutex_unlock(&sl->master->bus_mutex); - dev_dbg(&sl->dev, - "mutex unlocked, retries:%d", retries); - return 1; - } - } -error: + goto out; /* unrecoverable error */ + /* try again, the slave is ready for a command */ + } while (--retries); +out: mutex_unlock(&sl->master->bus_mutex); - dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", = retries); =20 - return -EIO; + dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n", + (bytes_written > 0) ? "succeeded" : "error", retries); + + return bytes_written; } =20 I can do a proper patch submission if you guys provide positive response = on this early RFC. Or better yet, you can take it and own it yourself as your v2 Mariusz. ;) > w1_buf[0] =3D W1_F29_FUNC_CHANN_ACCESS_WRITE; > w1_buf[1] =3D *buf; > w1_buf[2] =3D ~(*buf); > @@ -165,12 +172,8 @@ static ssize_t output_write(struct file *filp, = struct kobject *kobj, >=20 > readBack =3D w1_read_8(sl->master); >=20 > - if (readBack !=3D W1_F29_SUCCESS_CONFIRM_BYTE) { > - if (w1_reset_resume_command(sl->master)) > - goto error; > - /* try again, the slave is ready for a command = */ > + if (readBack !=3D W1_F29_SUCCESS_CONFIRM_BYTE) > continue; > - } >=20 > #ifdef CONFIG_W1_SLAVE_DS2408_READBACK > /* here the master could read another byte which > --=20 > 2.19.0.rc1 >=20