Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/i2c Fix a problem reported by jmcneill@ where by a s...



details:   https://anonhg.NetBSD.org/src/rev/a658bc1d88da
branches:  trunk
changeset: 322743:a658bc1d88da
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue May 15 02:02:18 2018 +0000

description:
Fix a problem reported by jmcneill@ where by a system with multuple i2c
busses would end up with "ghost" device instances on the second bus.  This
issue was previously masked on ARM systems by the empty-child-devices
array issue fixed recently (that effectively blocked all indirect config
of i2c busses on those systems).

To fix this problem, we require that indirectly-configured devices have
to fully specify their parent spec and address, e.g.:

foo* at iic0 addr 0x55

NOT

foo* at iic? addr ?

or even:

foo* at iic? addr 0x55

This is needed because of how indirect configuration works... attach
directives in the kernel config file are enumerated, calling the bus's
search routine, which in the case of i2c, enumerates all i2c addresses
and calls the match routine for each address.  Because we can't always
reliably probe for i2c devices, we ended up with erroneous matches.

Direct configuration of i2c is still allowed to use wildcarded parent specs
and locators.

diffstat:

 sys/dev/i2c/i2c.c |  19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diffs (54 lines):

diff -r 44c56380854c -r a658bc1d88da sys/dev/i2c/i2c.c
--- a/sys/dev/i2c/i2c.c Tue May 15 01:53:27 2018 +0000
+++ b/sys/dev/i2c/i2c.c Tue May 15 02:02:18 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i2c.c,v 1.57 2017/12/10 16:53:32 bouyer Exp $  */
+/*     $NetBSD: i2c.c,v 1.58 2018/05/15 02:02:18 thorpej Exp $ */
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.57 2017/12/10 16:53:32 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.58 2018/05/15 02:02:18 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -121,7 +121,7 @@
 {
        struct i2c_attach_args *ia = aux;
 
-       if (ia->ia_addr != (i2c_addr_t)-1)
+       if (ia->ia_addr != (i2c_addr_t)IICCF_ADDR_DEFAULT)
                aprint_normal(" addr 0x%x", ia->ia_addr);
 
        return UNCONF;
@@ -133,6 +133,16 @@
        struct iic_softc *sc = device_private(parent);
        struct i2c_attach_args ia;
 
+       /*
+        * I2C doesn't have any regular probing capability.  If we
+        * encounter a cfdata with a wild-carded address or a wild-
+        * carded parent spec, we skip them because they can only
+        * be used for direct-coniguration.
+        */
+       if (cf->cf_loc[IICCF_ADDR] == IICCF_ADDR_DEFAULT ||
+           cf->cf_pspec->cfp_unit == DVUNIT_ANY)
+               return 0;
+
        ia.ia_tag = sc->sc_tag;
        ia.ia_size = cf->cf_loc[IICCF_SIZE];
        ia.ia_type = sc->sc_type;
@@ -146,8 +156,7 @@
                if (sc->sc_devices[ia.ia_addr] != NULL)
                        continue;
 
-               if (cf->cf_loc[IICCF_ADDR] != -1 &&
-                   cf->cf_loc[IICCF_ADDR] != ia.ia_addr)
+               if (cf->cf_loc[IICCF_ADDR] != ia.ia_addr)
                        continue;
 
                if (config_match(parent, cf, &ia) > 0)



Home | Main Index | Thread Index | Old Index