Module Name:    src
Committed By:   christos
Date:           Sat Nov 13 13:36:43 UTC 2021

Modified Files:
        src/sys/dev/i2c: sht3x.c

Log Message:
Brad wants the __did_not_work code back :-)


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/i2c/sht3x.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/i2c/sht3x.c
diff -u src/sys/dev/i2c/sht3x.c:1.2 src/sys/dev/i2c/sht3x.c:1.3
--- src/sys/dev/i2c/sht3x.c:1.2	Fri Nov 12 17:16:27 2021
+++ src/sys/dev/i2c/sht3x.c	Sat Nov 13 08:36:42 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $	*/
+/*	$NetBSD: sht3x.c,v 1.3 2021/11/13 13:36:42 christos Exp $	*/
 
 /*
  * Copyright (c) 2021 Brad Spencer <b...@anduin.eldar.org>
@@ -17,7 +17,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.3 2021/11/13 13:36:42 christos Exp $");
 
 /*
   Driver for the Sensirion SHT30/SHT31/SHT35
@@ -41,7 +41,6 @@ __KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.
 #include <dev/i2c/sht3xreg.h>
 #include <dev/i2c/sht3xvar.h>
 
-
 static int	sht3x_take_break(void *, bool);
 static int	sht3x_get_status_register(void *, uint16_t *, bool);
 static int	sht3x_clear_status_register(void *, bool);
@@ -52,6 +51,18 @@ static int 	sht3x_match(device_t, cfdata
 static void 	sht3x_attach(device_t, device_t, void *);
 static int 	sht3x_detach(device_t, int);
 static void 	sht3x_refresh(struct sysmon_envsys *, envsys_data_t *);
+#ifdef __did_not_work
+/*
+ * The chip that I had would not allow the limits to actually be set
+ * for reasons which are not obvious.  The chip took the command just
+ * fine, but a read back of the limit registers showed that no change
+ * was made, so disable limits for now.
+ */
+static void	sht3x_get_limits(struct sysmon_envsys *, envsys_data_t *,
+    sysmon_envsys_lim_t *, uint32_t *);
+static void	sht3x_set_limits(struct sysmon_envsys *, envsys_data_t *,
+    sysmon_envsys_lim_t *, uint32_t *);
+#endif
 static int 	sht3x_verify_sysctl(SYSCTLFN_ARGS);
 static int 	sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS);
 static int 	sht3x_verify_sysctl_modes(SYSCTLFN_ARGS);
@@ -1166,6 +1177,9 @@ sht3x_attach(device_t parent, device_t s
 
 		sc->sc_sensors[i].units = sht3x_sensors[i].type;
 		sc->sc_sensors[i].state = ENVSYS_SINVALID;
+#ifdef __did_not_work
+		sc->sc_sensors[i].flags |= ENVSYS_FMONLIMITS;
+#endif
 
 		DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i,
 		    sc->sc_sensors[i].desc));
@@ -1182,6 +1196,10 @@ sht3x_attach(device_t parent, device_t s
 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
 	sc->sc_sme->sme_cookie = sc;
 	sc->sc_sme->sme_refresh = sht3x_refresh;
+#ifdef __did_not_work
+	sc->sc_sme->sme_get_limits = sht3x_get_limits;
+	sc->sc_sme->sme_set_limits = sht3x_set_limits;
+#endif
 
 	DPRINTF(sc, 2, ("sht3x_attach: registering with envsys\n"));
 
@@ -1348,6 +1366,38 @@ sht3x_parse_data(struct sht3x_sc *sc, en
 	return 0;
 }
 
+#ifdef __did_not_work
+/*
+ * These are the the same as above except solved for the raw tick rather than
+ * temperature or humidity.  These are needed for setting the alert limits, but
+ * since that did not work, disable these too for now.
+ */
+static uint16_t
+sht3x_compute_raw_from_temp(uint32_t temp)
+{
+	uint64_t i1;
+	uint32_t tempc;
+
+	tempc = temp - 272150000;
+	tempc = tempc / 1000000;
+
+	i1 = (13107 * tempc) + 589815;
+	return (uint16_t)(i1 / 35);
+}
+
+static uint16_t
+sht3x_compute_raw_from_rh(uint32_t mrh)
+{
+	uint64_t i1;
+	uint32_t rh;
+
+	rh = mrh / 1000000;
+
+	i1 = 13107 * rh;
+	return (uint16_t)(i1 / 20);
+}
+#endif
+
 static int
 sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata)
 {
@@ -1426,6 +1476,419 @@ sht3x_refresh(struct sysmon_envsys *sme,
 	mutex_exit(&sc->sc_mutex);
 }
 
+#ifdef __did_not_work
+static void
+sht3x_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
+    sysmon_envsys_lim_t *limits, uint32_t *props)
+{
+	struct sht3x_sc *sc = sme->sme_cookie;
+	uint16_t rawlimitshigh, rawlimitslow;
+	uint16_t templimithigh, rhlimithigh,
+	    templimitlow, rhlimitlow;
+	uint8_t templimithighmsb, templimithighlsb,
+	    templimitlowmsb, templimitlowlsb;
+	uint8_t rhlimithighmsb, rhlimithighlsb,
+	    rhlimitlowmsb, rhlimitlowlsb;
+	int error;
+	uint8_t lbuf[3];
+	uint8_t limitscrchigh, limitskcrchigh,
+	    limitscrclow, limitskcrclow;
+
+	*props = 0;
+
+	mutex_enter(&sc->sc_mutex);
+	error = iic_acquire_bus(sc->sc_tag, 0);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
+		    device_xname(sc->sc_dev), error));
+		mutex_exit(&sc->sc_mutex);
+		return;
+	}
+
+	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	rawlimitshigh = (lbuf[0] << 8) | lbuf[1];
+	limitskcrchigh = lbuf[2];
+	limitscrchigh = sht3x_crc(&lbuf[0],2);
+
+	templimithigh = ((rawlimitshigh & 0x1FF) << 7);
+	templimithighmsb = (uint8_t)(templimithigh >> 8);
+	templimithighlsb = (uint8_t)(templimithigh & 0x00FF);
+	DPRINTF(sc, 2, ("%s: Limits high intermediate temp: "
+	    "%04x %04x %02x %02x\n", device_xname(sc->sc_dev), rawlimitshigh,
+	    templimithigh, templimithighmsb, templimithighlsb));
+
+	rhlimithigh = (rawlimitshigh & 0xFE00);
+	rhlimithighmsb = (uint8_t)(rhlimithigh >> 8);
+	rhlimithighlsb = (uint8_t)(rhlimithigh & 0x00FF);
+	DPRINTF(sc, 2, ("%s: Limits high intermediate rh: "
+	    "%04x %04x %02x %02x\n", device_xname(sc->sc_dev), rawlimitshigh,
+	    rhlimithigh, rhlimithighmsb, rhlimithighlsb));
+
+	DPRINTF(sc, 2, ("%s: Limit high raw: %02x%02x %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2],
+	    limitscrchigh, limitskcrchigh));
+
+	error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	rawlimitslow = (lbuf[0] << 8) | lbuf[1];
+	limitskcrclow = lbuf[2];
+	limitscrclow = sht3x_crc(&lbuf[0],2);
+
+	templimitlow = ((rawlimitslow & 0x1FF) << 7);
+	templimitlowmsb = (uint8_t)(templimitlow >> 8);
+	templimitlowlsb = (uint8_t)(templimitlow & 0x00FF);
+	DPRINTF(sc, 2, ("%s: Limits low intermediate temp: "
+	    "%04x %04x %02x %02x\n", device_xname(sc->sc_dev), rawlimitslow,
+	    templimitlow, templimitlowmsb, templimitlowlsb));
+
+	rhlimitlow = (rawlimitslow & 0xFE00);
+	rhlimitlowmsb = (uint8_t)(rhlimitlow >> 8);
+	rhlimitlowlsb = (uint8_t)(rhlimitlow & 0x00FF);
+	DPRINTF(sc, 2, ("%s: Limits low intermediate rh: %04x %04x %02x %02x\n",
+	    device_xname(sc->sc_dev), rawlimitslow, rhlimitlow, rhlimitlowmsb,
+	    rhlimitlowlsb));
+
+	DPRINTF(sc, 2, ("%s: Limit low raw: %02x%02x %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2],
+	    limitscrclow, limitskcrclow));
+
+
+	switch (edata->sensor) {
+	case SHT3X_TEMP_SENSOR:
+		if (limitscrchigh == limitskcrchigh) {
+			limits->sel_critmax = sht3x_compute_temp_from_raw(
+			    templimithighmsb, templimithighlsb);
+			*props |= PROP_CRITMAX;
+		}
+		if (limitscrclow == limitskcrclow) {
+			limits->sel_critmin = sht3x_compute_temp_from_raw(
+			    templimitlowmsb, templimitlowlsb);
+			*props |= PROP_CRITMIN;
+		}
+		break;
+	case SHT3X_HUMIDITY_SENSOR:
+		if (limitscrchigh == limitskcrchigh) {
+			limits->sel_critmax = sht3x_compute_rh_from_raw(
+			    rhlimithighmsb, rhlimithighlsb);
+			*props |= PROP_CRITMAX;
+		}
+		if (limitscrclow == limitskcrclow) {
+			limits->sel_critmin = sht3x_compute_rh_from_raw(
+			    rhlimitlowmsb, rhlimitlowlsb);
+			*props |= PROP_CRITMIN;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (*props != 0)
+		*props |= PROP_DRIVER_LIMITS;
+
+	iic_release_bus(sc->sc_tag, 0);
+out:
+	mutex_exit(&sc->sc_mutex);
+}
+
+static void
+sht3x_set_alert_limits(void *aux, uint16_t high, uint16_t low, bool have_bus)
+{
+	struct sht3x_sc *sc = aux;
+	int error;
+	uint8_t hbuf[3];
+	uint8_t lbuf[3];
+
+	if (! have_bus) {
+		error = iic_acquire_bus(sc->sc_tag, 0);
+		if (error) {
+			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
+			    "setting alerts %d\n", device_xname(sc->sc_dev),
+			    error));
+			return;
+		}
+	}
+
+	hbuf[0] = high >> 8;
+	hbuf[1] = high & 0x00FF;
+	hbuf[2] = sht3x_crc(&hbuf[0],2);
+
+	lbuf[0] = low >> 8;
+	lbuf[1] = low & 0x00FF;
+	lbuf[2] = sht3x_crc(&lbuf[0],2);
+
+	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
+		    device_xname(sc->sc_dev), error));
+	}
+
+ out:
+	if (! have_bus) {
+		iic_release_bus(sc->sc_tag, 0);
+	}
+}
+
+static void
+sht3x_set_alert_limits2(void *aux, uint16_t high, uint16_t low,
+    uint16_t highminusone, uint16_t lowplusone, bool have_bus)
+{
+	struct sht3x_sc *sc;
+	sc = aux;
+
+	int error;
+	uint8_t hbuf[3];
+	uint8_t lbuf[3];
+	uint8_t hbufminusone[3];
+	uint8_t lbufplusone[3];
+
+	if (! have_bus) {
+		error = iic_acquire_bus(sc->sc_tag, 0);
+		if (error) {
+			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
+			    "setting alerts %d\n", device_xname(sc->sc_dev),
+			    error));
+			return;
+		}
+	}
+
+	hbuf[0] = high >> 8;
+	hbuf[1] = high & 0x00FF;
+	hbuf[2] = sht3x_crc(&hbuf[0],2);
+
+	lbuf[0] = low >> 8;
+	lbuf[1] = low & 0x00FF;
+	lbuf[2] = sht3x_crc(&lbuf[0],2);
+
+	hbufminusone[0] = highminusone >> 8;
+	hbufminusone[1] = highminusone & 0x00FF;
+	hbufminusone[2] = sht3x_crc(&hbufminusone[0],2);
+
+	lbufplusone[0] = lowplusone >> 8;
+	lbufplusone[1] = lowplusone & 0x00FF;
+	lbufplusone[2] = sht3x_crc(&lbufplusone[0],2);
+
+	DPRINTF(sc, 2, ("%s: Physical SET HIGH %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2]));
+	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	uint16_t sbuf;
+	int status_error;
+	status_error = sht3x_get_status_register(sc, &sbuf, true);
+	DPRINTF(sc, 2, ("%s: In SETTING, status register %04x -- %d\n",
+	    device_xname(sc->sc_dev), sbuf, status_error));
+
+	hbuf[0] = 0;
+	hbuf[1] = 0;
+	hbuf[2] = 0;
+	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, hbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not read high alert for SET %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+	DPRINTF(sc, 2, ("%s: Physical READBACK SET HIGH %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2]));
+
+	DPRINTF(sc, 2, ("%s: Physical CLEAR HIGH %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1],
+	    hbufminusone[2]));
+	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbufminusone, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+	hbufminusone[0] = 0;
+	hbufminusone[1] = 0;
+	hbufminusone[2] = 0;
+	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, hbufminusone, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not read high alert for CLEAR %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+	DPRINTF(sc, 2, ("%s: Physical READBACK CLEAR HIGH %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1],
+	    hbufminusone[2]));
+
+	DPRINTF(sc, 2, ("%s: Physical SET LOW %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2]));
+	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+	DPRINTF(sc, 2, ("%s: Physical CLEAR LOW %02x %02x %02x\n",
+	    device_xname(sc->sc_dev), lbufplusone[0], lbufplusone[1],
+	    lbufplusone[2]));
+	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbufplusone, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
+		    device_xname(sc->sc_dev), error));
+	}
+
+out:
+	if (! have_bus) {
+		iic_release_bus(sc->sc_tag, 0);
+	}
+}
+
+static void
+sht3x_set_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
+    sysmon_envsys_lim_t *limits, uint32_t *props)
+{
+	struct sht3x_sc *sc = sme->sme_cookie;
+	uint16_t rawlimitshigh, rawlimitslow;
+	uint16_t rawlimitshighclear, rawlimitslowclear;
+	uint16_t rawlimitshighminusone, rawlimitslowplusone;
+	int error;
+	uint8_t lbuf[3];
+	uint8_t limitscrchigh, limitskcrchigh, limitscrclow, limitskcrclow;
+	uint16_t limithigh, limitlow;
+	uint16_t limithighminusone, limitlowplusone;
+
+	if (limits == NULL) {
+		printf("XXX - Need to set back to default... limits is NULL\n");
+		return;
+	}
+
+	DPRINTF(sc, 2, ("%s: In set_limits - %d -- %d %d\n",
+	    device_xname(sc->sc_dev), edata->sensor,
+	    limits->sel_critmin, limits->sel_critmax));
+
+	mutex_enter(&sc->sc_mutex);
+	error = iic_acquire_bus(sc->sc_tag, 0);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	rawlimitshigh = (lbuf[0] << 8) | lbuf[1];
+	limitskcrchigh = lbuf[2];
+	limitscrchigh = sht3x_crc(&lbuf[0],2);
+
+
+	error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	rawlimitslow = (lbuf[0] << 8) | lbuf[1];
+	limitskcrclow = lbuf[2];
+	limitscrclow = sht3x_crc(&lbuf[0],2);
+
+	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	rawlimitshighclear = (lbuf[0] << 8) | lbuf[1];
+
+	error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_CLEAR, lbuf, 3);
+	if (error) {
+		DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n",
+		    device_xname(sc->sc_dev), error));
+		goto out;
+	}
+
+	rawlimitslowclear = (lbuf[0] << 8) | lbuf[1];
+
+	DPRINTF(sc, 2, ("%s: Set limits current raw limits %04x - %02x %02x ; "
+	    "%04x - %02x %02x ;; %04x %04x\n",
+	    device_xname(sc->sc_dev), rawlimitshigh, limitskcrchigh,
+	    limitscrchigh, rawlimitslow, limitskcrclow, limitscrclow,
+	    rawlimitshighclear, rawlimitslowclear));
+
+	switch (edata->sensor) {
+	case SHT3X_TEMP_SENSOR:
+		limithigh = sht3x_compute_raw_from_temp(limits->sel_critmax);
+		limitlow = sht3x_compute_raw_from_temp(limits->sel_critmin);
+		limithigh = limithigh >> 7;
+		limithighminusone = limithigh - 1;
+		limitlow = limitlow >> 7;
+		limitlowplusone = limitlow + 1;
+		rawlimitshigh = (rawlimitshigh & 0xFE00) | limithigh;
+		rawlimitshighminusone = (rawlimitshigh & 0xFE00) |
+		    limithighminusone;
+		rawlimitslow = (rawlimitslow & 0xFE00) | limitlow;
+		rawlimitslowplusone = (rawlimitslow & 0xFE00) | limitlowplusone;
+		DPRINTF(sc, 2, ("%s: Temp new raw limits high/low "
+		    "%04x %04x %04x %04x\n",
+		    device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow,
+		    rawlimitshighminusone, rawlimitslowplusone));
+		sht3x_set_alert_limits2(sc, rawlimitshigh, rawlimitslow,
+		    rawlimitshighminusone, rawlimitslowplusone, true);
+		break;
+	case SHT3X_HUMIDITY_SENSOR:
+		limithigh = sht3x_compute_raw_from_rh(limits->sel_critmax);
+		limitlow = sht3x_compute_raw_from_rh(limits->sel_critmin);
+		limithigh = limithigh & 0xFE00;
+		limitlow = limitlow & 0xFE00;
+		rawlimitshigh = (rawlimitshigh & 0x1FF) | limithigh;
+		rawlimitslow = (rawlimitslow & 0x1FF) | limitlow;
+		DPRINTF(sc, 2, ("%s: RH new raw limits high/low "
+		    "%04x %04x from %x %x\n",
+		    device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow, 
+		    limithigh, limitlow));
+		sht3x_set_alert_limits(sc, rawlimitshigh, rawlimitslow, true);
+		break;
+	default:
+		break;
+	}
+
+	iic_release_bus(sc->sc_tag, 0);
+ out:
+	mutex_exit(&sc->sc_mutex);
+}
+#endif
+
 static int
 sht3xopen(dev_t dev, int flags, int fmt, struct lwp *l)
 {

Reply via email to