Subject: kern/27088: m41t00 RTC on I2C has 0-length command, should be 1-length
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <j.momose@ieee.org>
List: netbsd-bugs
Date: 09/30/2004 13:21:50
>Number:         27088
>Category:       kern
>Synopsis:       m41t00 RTC on I2C has 0-length command, should be 1-length
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Sep 30 13:22:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Jared Momose
>Release:        current
>Organization:
>Environment:
NetBSD evileye.rrg.ams.apc.com 2.0_BETA NetBSD 2.0_BETA (GENERIC) #0:Fri Jun 25 18:44:27 UTC 2004 autobuild@tgm.netbsd.org:/autobuild/netbsd-20/i386/OBJ/autobuild/netbsd-2-0/src/sys/arch/i386/compile/GENERIC i386
>Description:
The file src/sys/dev/i2c/m41t00.c has a small bug in the read function. The I2C command byte length is specified as 0, when it should be 1. This bug is seen on systems with a part that has the RTC *AND* NVRAM like the m41t11. With the command length as 0, a random seek to a byte in the part is not allowed.

>How-To-Repeat:
You will need a system with a m41txx part which has both RTC and NVRAM.

The following will write "asdf" to bytes 9-12, which is the first 4 bytes of NVRAM.

echo -n "asdf" | dd of=/dev/m41trtc0 bs=1 seek=8

The following does not return "asdf" as it should, but rather the first four bytes of the RTC region.

dd if=/dev/m41trtc0 bs=1 skip=8 count=4

>Fix:
The following patch fixes the problem:

--- m41t00.c.orig       2004-09-20 09:38:13.000000000 -0400
+++ m41t00.c    2004-09-30 05:11:49.000000000 -0400
@@ -171,7 +171,7 @@
                a = (int)uio->uio_offset;
                cmdbuf[0] = a;
                if ((error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
-                                     sc->sc_address, cmdbuf, 0,
+                                     sc->sc_address, cmdbuf, 1,
                                      &ch, 1, 0)) != 0) {
                        iic_release_bus(sc->sc_tag, 0);
                        printf("%s: m41t00_read: read failed at 0x%x\n",

>Release-Note:
>Audit-Trail:
>Unformatted: