Subject: kern/32913: amdpm(4) smbus/i2cbus needs locking
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <njoly@pasteur.fr>
List: netbsd-bugs
Date: 02/23/2006 14:25:00
>Number:         32913
>Category:       kern
>Synopsis:       amdpm(4) smbus/i2cbus needs locking
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 23 14:25:00 +0000 2006
>Originator:     Nicolas Joly
>Release:        NetBSD 3.99.15
>Organization:
Institut Pasteur, Paris.
>Environment:
System: NetBSD lanfeust.sis.pasteur.fr 3.99.15 NetBSD 3.99.15 (LANFEUST) #10: Tue Feb 21 18:54:54 CET 2006 njoly@lanfeust.sis.pasteur.fr:/local/src/NetBSD/obj/amd64/sys/arch/amd64/compile/LANFEUST amd64
Architecture: x86_64
Machine: amd64
>Description:
While looking at the amdpm(4) smbus code, i noticed that i2c locking is
currently a no-op. This may cause trouble if multiples devices try to
talk on the smbus/i2cbus at the same time.

NB: While here, add multiple inclusion protection to `sys/dev/pci/amdpmvar.h'
header file.
>How-To-Repeat:
code inspection
>Fix:
Index: sys/dev/pci/amdpm_smbus.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/amdpm_smbus.c,v
retrieving revision 1.2
diff -u -r1.2 amdpm_smbus.c
--- sys/dev/pci/amdpm_smbus.c	19 Feb 2006 08:49:45 -0000	1.2
+++ sys/dev/pci/amdpm_smbus.c	21 Feb 2006 17:56:01 -0000
@@ -80,6 +80,8 @@
 	sc->sc_i2c.ic_read_byte = NULL;
 	sc->sc_i2c.ic_write_byte = NULL;
 	sc->sc_i2c.ic_exec = amdpm_smbus_exec;
+
+	lockinit(&sc->sc_lock, PZERO, "amdpm_smbus", 0, 0);
       
 	iba.iba_name = "iic";
 	iba.iba_tag = &sc->sc_i2c;
@@ -89,12 +91,22 @@
 static int
 amdpm_smbus_acquire_bus(void *cookie, int flags)
 {
-	return (0);
+	struct amdpm_softc *sc = cookie;
+	int err;
+
+	err = lockmgr(&sc->sc_lock, LK_EXCLUSIVE, NULL);
+
+	return err;
 }
 
 static void
 amdpm_smbus_release_bus(void *cookie, int flags)
 {
+	struct amdpm_softc *sc = cookie;
+
+	lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
+
+	return;
 }
 
 static int
Index: sys/dev/pci/amdpmvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/amdpmvar.h,v
retrieving revision 1.1
diff -u -r1.1 amdpmvar.h
--- sys/dev/pci/amdpmvar.h	19 Feb 2006 02:24:20 -0000	1.1
+++ sys/dev/pci/amdpmvar.h	21 Feb 2006 17:56:01 -0000
@@ -35,6 +35,12 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+
+#ifndef _DEV_PCI_AMDPMVAR_H_
+#define _DEV_PCI_AMDPMVAR_H_
+
+#include <sys/lock.h>
+
 struct amdpm_softc {
 	struct device sc_dev;
 
@@ -46,6 +52,7 @@
 
 	i2c_addr_t sc_smbus_slaveaddr;		/* address of smbus slave */
 	struct i2c_controller sc_i2c;		/* i2c controller info */
+	struct lock sc_lock;
 
 	struct callout sc_rnd_ch;
 	rndsource_element_t sc_rnd_source;
@@ -55,3 +62,5 @@
 	struct evcnt sc_rnd_data[256];
 #endif
 };
+
+#endif /* _DEV_PCI_AMDPMVAR_H_ */