From owner-svn-src-head@freebsd.org Thu Jun 29 00:29:17 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 032C9D887BA; Thu, 29 Jun 2017 00:29:17 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C421768650; Thu, 29 Jun 2017 00:29:16 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v5T0TF1J094108; Thu, 29 Jun 2017 00:29:15 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v5T0TFlB094107; Thu, 29 Jun 2017 00:29:15 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201706290029.v5T0TFlB094107@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Thu, 29 Jun 2017 00:29:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320460 - head/sys/dev/iicbus X-SVN-Group: head X-SVN-Commit-Author: ian X-SVN-Commit-Paths: head/sys/dev/iicbus X-SVN-Commit-Revision: 320460 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Jun 2017 00:29:17 -0000 Author: ian Date: Thu Jun 29 00:29:15 2017 New Revision: 320460 URL: https://svnweb.freebsd.org/changeset/base/320460 Log: If an i2c transfer ends due to error, issue a stop on the bus even if the nostop option is set, if a start was issued. The nostop option doesn't mean "never issue a stop" it means "only issue a stop after the last in a series of transfers". If the transfer ends due to error, then that was the last transfer in the series, and a stop is required. Before this change, any error during a transfer when nostop is set would effectively hang the bus, because sc->started would never get cleared, and that caused all future calls to iicbus_start() to return an error because it looked like the bus was already active. (Unrelated errors in handling the nostop option, to be addressed separately, could lead to this bus hang condition even on busses that don't set the nostop option.) Modified: head/sys/dev/iicbus/iiconf.c Modified: head/sys/dev/iicbus/iiconf.c ============================================================================== --- head/sys/dev/iicbus/iiconf.c Wed Jun 28 21:45:13 2017 (r320459) +++ head/sys/dev/iicbus/iiconf.c Thu Jun 29 00:29:15 2017 (r320460) @@ -419,7 +419,7 @@ iicbus_transfer_gen(device_t dev, struct iic_msg *msgs { int i, error, lenread, lenwrote, nkid, rpstart, addr; device_t *children, bus; - bool nostop; + bool nostop, started; if ((error = device_get_children(dev, &children, &nkid)) != 0) return (IIC_ERESOURCE); @@ -431,6 +431,7 @@ iicbus_transfer_gen(device_t dev, struct iic_msg *msgs rpstart = 0; free(children, M_TEMP); nostop = iicbus_get_nostop(dev); + started = false; for (i = 0, error = 0; i < nmsgs && error == 0; i++) { addr = msgs[i].slave; if (msgs[i].flags & IIC_M_RD) @@ -443,9 +444,10 @@ iicbus_transfer_gen(device_t dev, struct iic_msg *msgs error = iicbus_repeated_start(bus, addr, 0); else error = iicbus_start(bus, addr, 0); + if (error != 0) + break; + started = true; } - if (error != 0) - break; if (msgs[i].flags & IIC_M_RD) error = iicbus_read(bus, msgs[i].buf, msgs[i].len, @@ -464,7 +466,7 @@ iicbus_transfer_gen(device_t dev, struct iic_msg *msgs iicbus_stop(bus); } } - if (error != 0 && !nostop) + if (error != 0 && started) iicbus_stop(bus); return (error); }