Subject: kern/32885: adt7463 i2c device does not always unlock i2c bus on error
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <njoly@pasteur.fr>
List: netbsd-bugs
Date: 02/20/2006 18:40:00
>Number: 32885
>Category: kern
>Synopsis: adt7463 i2c device does not always unlock i2c bus on error
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Feb 20 18:40: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) #7: Mon Feb 20 19:09:04 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 adt7463 code, i noticed that it will not unlock the i2c bus if
iic_exec() function fails ... 3 functions are involved: adt7463c_receive_1(),
adt7463c_send_1() and adt7463c_write_1().
While here add a missing newline, to make the boot messages nicer on my -current
NetBSD/amd64 workstation (Tyan S2885 motherboard):
OLD:
amdpm0 at pci0 dev 7 function 3: Advanced Micro Devices AMD8111 ACPI Controller (rev. 0x05)
iic0 at amdpm0: I2C bus
adt7463c0 at iic0 addr 0x2eamdpm0: random number generator enabled (apprx. 58ms)
NEW:
amdpm0 at pci0 dev 7 function 3: Advanced Micro Devices AMD8111 ACPI Controller (rev. 0x05)
iic0 at amdpm0: I2C bus
adt7463c0 at iic0 addr 0x2e
amdpm0: random number generator enabled (apprx. 58ms)
>How-To-Repeat:
code inspection, because amdpm(4) SMBus locking is a no-op for now.
>Fix:
Index: sys/dev/i2c/adt7463.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/adt7463.c,v
retrieving revision 1.2
diff -u -r1.2 adt7463.c
--- sys/dev/i2c/adt7463.c 19 Feb 2006 08:40:12 -0000 1.2
+++ sys/dev/i2c/adt7463.c 20 Feb 2006 18:17:26 -0000
@@ -90,6 +90,8 @@
struct adt7463c_softc *sc = (struct adt7463c_softc *)self;
struct i2c_attach_args *ia = aux;
int i = 0;
+
+ printf("\n");
sc->sc_tag = ia->ia_tag;
sc->sc_address = ia->ia_addr;
@@ -359,8 +361,10 @@
return (error);
if ((error = iic_exec(sc->sc_tag, I2C_OP_READ,
- sc->sc_address, NULL, 0, &val, 1, 0)) != 0)
+ sc->sc_address, NULL, 0, &val, 1, 0)) != 0) {
+ iic_release_bus(sc->sc_tag, 0);
return (error);
+ }
iic_release_bus(sc->sc_tag, 0);
return (val);
@@ -374,8 +378,10 @@
return (error);
if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE,
- sc->sc_address, NULL, 0, &val, 1, 0)) != 0)
+ sc->sc_address, NULL, 0, &val, 1, 0)) != 0) {
+ iic_release_bus(sc->sc_tag, 0);
return (error);
+ }
iic_release_bus(sc->sc_tag, 0);
return (0);
@@ -389,8 +395,10 @@
return (error);
if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE,
- sc->sc_address, &cmd, 1, &val, 1, 0)) != 0)
+ sc->sc_address, &cmd, 1, &val, 1, 0)) != 0) {
+ iic_release_bus(sc->sc_tag, 0);
return (error);
+ }
iic_release_bus(sc->sc_tag, 0);
return (0);