NetBSD-Bugs archive

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

Re: port-sparc64/54211: esiop stopped detecting boot disk



Hi,

> I think that it also makes sense to either remove indirect matching or make
> admtemp more resistant to false matches.  This would also cover other cases.

Can you try the attached, please?  It probes to check if the detected chip
is an adm1021 or clone.  It should fail to match here, so restoring the old
behaviour.

Regards,

Julian
--- sys/dev/i2c/adm1021.c.dist	2019-12-07 15:58:05.209974319 +0100
+++ sys/dev/i2c/adm1021.c	2019-12-10 03:06:31.239950413 +0100
@@ -131,7 +131,13 @@
 	uint8_t sc_thermlim[ADMTEMP_NUM_SENSORS];
 };
 
+static int	admtemp_ident(struct admtemp_softc *);
 int	admtemp_match(device_t, cfdata_t, void *);
+static int	admtemp_exec(struct admtemp_softc *, i2c_op_t,
+			uint8_t *, uint8_t *);
+static void	admtemp_setflags(struct admtemp_softc *,
+			struct i2c_attach_args *, uint8_t *,
+			uint8_t *, char* );
 void	admtemp_attach(device_t, device_t, void *);
 void	admtemp_refresh(struct sysmon_envsys *, envsys_data_t *);
 void	admtemp_getlim_1021(struct sysmon_envsys *, envsys_data_t *,
@@ -158,12 +164,34 @@
 	{ NULL,				0 }
 };
 
+/* Check company ID for possible matches */
+static int
+admtemp_ident(struct admtemp_softc *sc)
+{
+	uint8_t cmd, comp;
+	int err;
+
+	comp = 0;
+	cmd = ADM1021_COMPANY;
+	err = admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &comp);
+	if (err)
+		return 0;
+	if (comp == 0 || comp == ADM1021_COMPANY_MAXIM ||
+	    comp == ADM1021_COMPANY_GMT || comp == ADM1021_COMPANY_ADM)
+		return 1;
+	return 0;
+}
+
 int
 admtemp_match(device_t parent, cfdata_t match, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
+	struct admtemp_softc sc;	/* For chip ident */
 	int match_result;
 
+	sc.sc_tag = ia->ia_tag;
+	sc.sc_addr = ia->ia_addr;
+
 	if (iic_use_direct_match(ia, match, compat_data, &match_result))
 		return match_result;
 	
@@ -171,10 +199,11 @@
 	 * Indirect config - not much we can do!
 	 * Check typical addresses.
 	 */
-	if (((ia->ia_addr >= 0x18) && (ia->ia_addr <= 0x1a)) ||
+	if ((((ia->ia_addr >= 0x18) && (ia->ia_addr <= 0x1a)) ||
 	    ((ia->ia_addr >= 0x29) && (ia->ia_addr <= 0x2b)) ||
-	    ((ia->ia_addr >= 0x48) && (ia->ia_addr <= 0x4e)))
-		return I2C_MATCH_ADDRESS_ONLY;
+	    ((ia->ia_addr >= 0x48) && (ia->ia_addr <= 0x4e))) &&
+	    admtemp_ident(&sc))
+		return I2C_MATCH_ADDRESS_AND_PROBE;
 
 	return 0;
 }
@@ -207,7 +236,7 @@
  */
 static void
 admtemp_setflags(struct admtemp_softc *sc, struct i2c_attach_args *ia,
-    uint8_t* comp, uint8_t *rev, char* name)
+    uint8_t *comp, uint8_t *rev, char* name)
 {
 	uint8_t cmd, data, tmp;
 	int i;


Home | Main Index | Thread Index | Old Index