Re: diff: trigger acpiac_refresh when acpibat notification
On Thu, 17 Aug 2023 at 16:12:07 +0900, YASUOKA Masahiko wrote: > Hi, > > Update the AC status when the battery notification is happened. > Because the AC status notification doesn't happen on some machines. > My vaio actually has this problem. > > Also Linux is doing the same thing > > https://github.com/torvalds/linux/blob/v6.4/drivers/acpi/ac.c#L165-L183 > > ok? comments? When does acpiac_notify_triggered get reset back to 0 to run again on the next battery notification? > Index: sys/dev/acpi/acpiac.c > === > RCS file: /cvs/src/sys/dev/acpi/acpiac.c,v > retrieving revision 1.36 > diff -u -p -r1.36 acpiac.c > --- sys/dev/acpi/acpiac.c 6 Apr 2022 18:59:27 - 1.36 > +++ sys/dev/acpi/acpiac.c 17 Aug 2023 06:57:44 - > @@ -140,6 +140,8 @@ acpiac_getpsr(struct acpiac_softc *sc) > return (0); > } > > +static int acpiac_notify_triggered = 0; > + > int > acpiac_notify(struct aml_node *node, int notify_type, void *arg) > { > @@ -148,6 +150,8 @@ acpiac_notify(struct aml_node *node, int > dnprintf(10, "acpiac_notify: %.2x %s\n", notify_type, > DEVNAME(sc)); > > + acpiac_notify_triggered = 1; > + > switch (notify_type) { > case 0x00: > case 0x01: > @@ -164,4 +168,22 @@ acpiac_notify(struct aml_node *node, int > break; > } > return (0); > +} > + > +void > +acpiac_battery_notify(void) > +{ > + struct acpi_softc *sc = acpi_softc; > + struct acpi_ac *ac; > + > + if (acpiac_notify_triggered) > + return; > + /* > + * On some machines (vaio VJPK23 at least) AC status notifications > + * are not triggered. Update the AC status when battery notifications. > + */ > + SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { > + acpiac_refresh(ac->aac_softc); > + acpi_record_event(sc, APM_POWER_CHANGE); > + } > } > Index: sys/dev/acpi/acpibat.c > === > RCS file: /cvs/src/sys/dev/acpi/acpibat.c,v > retrieving revision 1.70 > diff -u -p -r1.70 acpibat.c > --- sys/dev/acpi/acpibat.c6 Apr 2022 18:59:27 - 1.70 > +++ sys/dev/acpi/acpibat.c17 Aug 2023 06:57:45 - > @@ -536,5 +536,7 @@ acpibat_notify(struct aml_node *node, in > acpibat_refresh(sc); > acpi_record_event(sc->sc_acpi, APM_POWER_CHANGE); > > + acpiac_battery_notify(); > + > return (0); > } > Index: sys/dev/acpi/acpidev.h > === > RCS file: /cvs/src/sys/dev/acpi/acpidev.h,v > retrieving revision 1.44 > diff -u -p -r1.44 acpidev.h > --- sys/dev/acpi/acpidev.h29 Jun 2018 17:39:18 - 1.44 > +++ sys/dev/acpi/acpidev.h17 Aug 2023 06:57:45 - > @@ -306,6 +306,8 @@ struct acpiac_softc { > struct ksensordev sc_sensdev; > }; > > +void acpiac_battery_notify(void); > + > struct acpibat_softc { > struct device sc_dev; > >
ietp cleanup
bmercer@ noticed there was no newline printed after a successful attachment. I did some other minor cleanup removing duplicate dv_xname printing during attachment and wrapping at 80 chars. ok? Index: sys/dev/i2c/ietp.c === RCS file: /cvs/src/sys/dev/i2c/ietp.c,v retrieving revision 1.1 diff -u -p -u -p -r1.1 ietp.c --- sys/dev/i2c/ietp.c 8 Jul 2023 02:43:02 - 1.1 +++ sys/dev/i2c/ietp.c 20 Jul 2023 17:55:40 - @@ -1,6 +1,6 @@ /* $OpenBSD: ietp.c,v 1.1 2023/07/08 02:43:02 jcs Exp $ */ /* - * elan-i2c driver + * Elan I2C Touchpad driver * * Copyright (c) 2015, 2016 joshua stein * Copyright (c) 2020, 2022 Vladimir Kondratyev @@ -19,9 +19,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* Protocol documentation: https://lkml.indiana.edu/hypermail/linux/kernel/1205.0/02551.html. - Based on FreeBSD ietp driver. -*/ +/* Protocol documentation: + * https://lkml.indiana.edu/hypermail/linux/kernel/1205.0/02551.html + * Based on FreeBSD ietp driver. + */ #include #include @@ -166,7 +167,7 @@ ietp_attach(struct device *parent, struc sc->sc_ih = iic_intr_establish(sc->sc_tag, ia->ia_intr, IPL_TTY, ietp_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { - printf(", can't establish interrupt"); + printf(", can't establish interrupt\n"); return; } } @@ -177,13 +178,13 @@ ietp_attach(struct device *parent, struc buf8 = (uint8_t *)&buf; if (ietp_iic_read_reg(sc, IETP_UNIQUEID, sizeof(buf), &buf) != 0) { - printf("%s: failed reading product ID\n", sc->sc_dev.dv_xname); + printf(": failed reading product ID\n"); return; } sc->product_id = le16toh(buf); if (ietp_iic_read_reg(sc, IETP_PATTERN, sizeof(buf), &buf) != 0) { - printf("%s: failed reading pattern\n", sc->sc_dev.dv_xname); + printf(": failed reading pattern\n"); return; } pattern = buf == 0x ? 0 : buf8[1]; @@ -191,61 +192,62 @@ ietp_attach(struct device *parent, struc reg = pattern >= 0x01 ? IETP_IC_TYPE : IETP_OSM_VERSION; if (ietp_iic_read_reg(sc, reg, sizeof(buf), &buf) != 0) { - printf("%s: failed reading IC type\n", sc->sc_dev.dv_xname); + printf(": failed reading IC type\n"); return; } sc->ic_type = pattern >= 0x01 ? be16toh(buf) : buf8[1]; if (ietp_iic_read_reg(sc, IETP_NSM_VERSION, sizeof(buf), &buf) != 0) { - printf("%s: failed reading SM version\n", sc->sc_dev.dv_xname); + printf(": failed reading SM version\n"); return; } sc->is_clickpad = (buf8[0] & 0x10) != 0; if (ietp_iic_set_absolute_mode(sc, true) != 0) { - printf("%s: failed to set absolute mode\n", sc->sc_dev.dv_xname); + printf(": failed to set absolute mode\n"); return; } if (ietp_iic_read_reg(sc, IETP_MAX_X_AXIS, sizeof(buf), &buf) != 0) { - printf("%s: failed reading max x\n", sc->sc_dev.dv_xname); + printf(": failed reading max x\n"); return; } sc->max_x = le16toh(buf); if (ietp_iic_read_reg(sc, IETP_MAX_Y_AXIS, sizeof(buf), &buf) != 0) { - printf("%s: failed reading max y\n", sc->sc_dev.dv_xname); + printf(": failed reading max y\n"); return; } sc->max_y = le16toh(buf); if (ietp_iic_read_reg(sc, IETP_TRACENUM, sizeof(buf), &buf) != 0) { - printf("%s: failed reading trace info\n", sc->sc_dev.dv_xname); + printf(": failed reading trace info\n"); return; } sc->trace_x = sc->max_x / buf8[0]; sc->trace_y = sc->max_y / buf8[1]; if (ietp_iic_read_reg(sc, IETP_PRESSURE, sizeof(buf), &buf) != 0) { - printf("%s: failed reading pressure format\n", sc->sc_dev.dv_xname); + printf(": failed reading pressure format\n"); return; } sc->pressure_base = (buf8[0] & 0x10) ? 0 : IETP_PRESSURE_BASE; if (ietp_iic_read_reg(sc, IETP_RESOLUTION, sizeof(buf), &buf) != 0) { - printf("%s: failed reading resolution\n", sc->sc_dev.dv_xname); + printf(": failed reading resolution\n"); return; } /* Conversion from internal format
Re: [PATCH] Elantech touchpad I2C deiver
mset(&ia, 0, sizeof(ia)); > + ia.ia_tag = sc->sc_iba.iba_tag; > + ia.ia_size = 1; > + ia.ia_name = "ietp"; > + ia.ia_addr = crs.i2c_addr; > + ia.ia_cookie = dev; > + > + if (sc->sc_poll_ihidev) > + ia.ia_poll = 1; > + if (!(crs.irq_int == 0 && crs.gpio_int_node == NULL)) > + ia.ia_intr = &crs; > + > + if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) { > + node->parent->attached = 1; > + return 0; > + } > + > + return 1; > +} > + > int > dwiic_acpi_found_iatp(struct dwiic_softc *sc, struct aml_node *node, char > *dev, > struct dwiic_crs crs) > diff --git sys/dev/i2c/files.i2c sys/dev/i2c/files.i2c > index fd7d61da9..16faef9aa 100644 > --- sys/dev/i2c/files.i2c > +++ sys/dev/i2c/files.i2c > @@ -230,6 +230,11 @@ device iatp: wsmousedev > attach iatp at i2c > file dev/i2c/iatp.c iatp > > +# Elantech touchpad > +device ietp: wsmousedev > +attach ietp at i2c > +file dev/i2c/ietp.c ietp > + > # Bosch BMC150 6-axis eCompass > device bgw > attach bgw at i2c > diff --git sys/dev/i2c/ietp.c sys/dev/i2c/ietp.c > new file mode 100644 > index 0..49d61b351 > --- /dev/null > +++ sys/dev/i2c/ietp.c > @@ -0,0 +1,788 @@ > +/* $OpenBSD: elantp.c,v 1.28 2023/07/04 15:14:01 kettenis Exp $ */ > +/* > + * elan-i2c driver Is there a URL to a document somewhere where any of this protocol info comes from? > + * > + * Copyright (c) 2015, 2016 joshua stein > + * Copyright (c) 2020, 2022 Vladimir Kondratyev > + * Copyright (c) 2023 vladimir serbinenko > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include > +#include > + > +/* #define IETP_DEBUG */ > + > +#ifdef IETP_DEBUG > +#define DPRINTF(x) printf x > +#else > +#define DPRINTF(x) > +#endif > + > +#define SLOW_POLL_MS 200 > +#define FAST_POLL_MS 10 All polling code should probably be removed. Polling was only added to ihidev as a workaround for an issue with our ACPI code which was failing to enable interrupts properly, but has since been fixed. > + > +enum { > + I2C_HID_CMD_DESCR = 0x0, > + I2C_HID_CMD_RESET = 0x1, > + I2C_HID_CMD_GET_REPORT = 0x2, > + I2C_HID_CMD_SET_REPORT = 0x3, > + I2C_HID_CMD_SET_POWER = 0x8, > +}; > + > +#define I2C_HID_POWER_ON 0x0 > +#define I2C_HID_POWER_OFF0x1 > + > +#define IETP_PATTERN0x0100 > +#define IETP_UNIQUEID 0x0101 > +#define IETP_IC_TYPE0x0103 > +#define IETP_OSM_VERSION0x0103 > +#define IETP_NSM_VERSION0x0104 > +#define IETP_TRACENUM 0x0105 > +#define IETP_MAX_X_AXIS 0x0106 > +#define IETP_MAX_Y_AXIS 0x0107 > +#define IETP_RESOLUTION 0x0108 > +#define IETP_PRESSURE 0x010A > + > +#define IETP_CONTROL0x0300 > +#define IETP_CTRL_ABSOLUTE 0x0001 > +#define IETP_CTRL_STANDARD 0x > + > +#define IETP_REPORT_LEN_LO 31 > +#define IETP_REPORT_LEN_HI 36 > +#define IETP_MAX_FINGERS5 > + > +#define IETP_REPORT_ID_LO 0x5D > +#define IETP_REPORT_ID_HI 0x60 > + > +#define IETP_TOUCH_INFO 0 > +#define IETP_FINGER_DATA1 > +#define IETP_FINGER_DATA_LEN5 > +#define IETP_WH_DATA31 > + > +#define IETP_TOUCH_LMB (1 << 0) > +#define IETP_TOUCH_RMB (1 << 1) > +#define IETP_TOUCH_MMB (1 << 2) > + > +#define IETP_MAX_PRESSURE 255 > +#define IETP_FWIDTH_REDUCE 90 > +#define IETP_PRESSURE_BASE 25 &g
Re: acpithinkpad: don't setup non-existent temp sensors
On Fri, 07 Apr 2023 at 19:00:43 +, Klemens Nanni wrote: > > + sc->sc_ntempsens = 0; > > + for (i = 0; i < THINKPAD_NSENSORS - THINKPAD_SENSOR_TMP0; i++) { > > + if (thinkpad_get_temp(sc, i, &tmp) != 0) > > + break; > > doesn't this mean, that legit sensors which happen to fail this read > upon attach won't ever be visible at runtime? > > I have no idea how reliable those sensors are, but given that the code > handles spurious failure, this seems not too far fetched. The sensor nodes (TMP0, TMP1, etc.) are hard-coded into the DSDT, so the EC failing to read the actual sensor should still allow it to be found. > > - /* On version 2 and newer, let *drm or acpivout control brightness */ > > - if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION1 && > > - (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", > > - 0, NULL, &sc->sc_brightness) == 0)) { > > + if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", > > + 0, NULL, &sc->sc_brightness) == 0) { > > ws_get_param = thinkpad_get_param; > > ws_set_param = thinkpad_set_param; > > } > > Is this an unrelated diff that snuck in? Yes, here is a new version without that chunk. > > + if (aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode, sname, 0, 0, > > + temp) != 0) > > + return (1); > > Looks liks aml_evalnode(9) only returns 0/success or > ACPI_E_BADVALUE/failure anyway, so there's no way to distinguish between > nonexistent sensors and existent but failing sensors, right? Correct, this is just reporting whether the node exists and can be read, not whether the sensor is broken or reporting bogus values. Index: acpithinkpad.c === RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.70 diff -u -p -u -p -r1.70 acpithinkpad.c --- acpithinkpad.c 6 Apr 2022 18:59:27 - 1.70 +++ acpithinkpad.c 8 Apr 2023 15:03:09 - @@ -112,11 +112,10 @@ #defineTHINKPAD_TABLET_SCREEN_CHANGED 0x60c0 #defineTHINKPAD_SWITCH_WIRELESS0x7000 -#define THINKPAD_NSENSORS 10 -#define THINKPAD_NTEMPSENSORS 8 - -#define THINKPAD_SENSOR_FANRPM THINKPAD_NTEMPSENSORS -#define THINKPAD_SENSOR_PORTREPL THINKPAD_NTEMPSENSORS + 1 +#define THINKPAD_SENSOR_FANRPM 0 +#define THINKPAD_SENSOR_PORTREPL 1 +#define THINKPAD_SENSOR_TMP0 2 +#define THINKPAD_NSENSORS 10 #define THINKPAD_ECOFFSET_VOLUME 0x30 #define THINKPAD_ECOFFSET_VOLUME_MUTE_MASK 0x40 @@ -140,6 +139,7 @@ struct acpithinkpad_softc { struct ksensor sc_sens[THINKPAD_NSENSORS]; struct ksensordevsc_sensdev; + int sc_ntempsens; uint64_t sc_hkey_version; @@ -178,6 +178,7 @@ int thinkpad_get_brightness(struct acpit intthinkpad_set_brightness(void *, int); intthinkpad_get_param(struct wsdisplay_param *); intthinkpad_set_param(struct wsdisplay_param *); +intthinkpad_get_temp(struct acpithinkpad_softc *, int, int64_t *); voidthinkpad_sensor_attach(struct acpithinkpad_softc *sc); voidthinkpad_sensor_refresh(void *); @@ -228,6 +229,7 @@ thinkpad_match(struct device *parent, vo void thinkpad_sensor_attach(struct acpithinkpad_softc *sc) { + int64_t tmp; int i; if (sc->sc_acpi->sc_ec == NULL) @@ -237,10 +239,16 @@ thinkpad_sensor_attach(struct acpithinkp /* Add temperature probes */ strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), sizeof(sc->sc_sensdev.xname)); - for (i=0; isc_sens[i].type = SENSOR_TEMP; - sensor_attach(&sc->sc_sensdev, &sc->sc_sens[i]); - } + sc->sc_ntempsens = 0; + for (i = 0; i < THINKPAD_NSENSORS - THINKPAD_SENSOR_TMP0; i++) { + if (thinkpad_get_temp(sc, i, &tmp) != 0) + break; + + sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].type = SENSOR_TEMP; + sensor_attach(&sc->sc_sensdev, + &sc->sc_sens[THINKPAD_SENSOR_TMP0 + i]); + sc->sc_ntempsens++; + } /* Add fan probe */ sc->sc_sens[THINKPAD_SENSOR_FANRPM].type = SENSOR_FANRPM; @@ -262,17 +270,19 @@ thinkpad_sensor_refresh(void *arg) struct acpithinkpad_softc *sc = arg; uint8_t lo, hi, i; int64_t tmp; - char sname[5]; /* Refresh sensor readings */ - for (i=0; isc_acpi, sc->sc_ec->sc_devnode, - sname, 0, 0, &tmp); - sc->sc_sens[i].value = (tmp * 100) + 27315; - if (tmp > 127 || tmp < -127) - sc->sc_sens[i].flags = SENSOR_FINVALID; - } + for (i = 0; i < sc->sc_ntempsens; i++) { + if (thinkpad_get_temp(sc, i, &tmp) != 0) { + sc->sc_sens[i].flags = SENSOR_FINVALID; + continue; +
acpithinkpad: don't setup non-existent temp sensors
acpithinkpad sets up a hard-coded number of temperature sensors and doesn't check the result of aml_evalinteger when polling, so for all invalid sensors it ends up reporting the value of the previous successful sensor check resulting in this (for a machine with only a TMP0 sensor): hw.sensors.acpithinkpad0.temp0=47.00 degC hw.sensors.acpithinkpad0.temp1=47.00 degC hw.sensors.acpithinkpad0.temp2=47.00 degC hw.sensors.acpithinkpad0.temp3=47.00 degC hw.sensors.acpithinkpad0.temp4=47.00 degC hw.sensors.acpithinkpad0.temp5=47.00 degC hw.sensors.acpithinkpad0.temp6=47.00 degC hw.sensors.acpithinkpad0.temp7=47.00 degC hw.sensors.acpithinkpad0.fan0=3605 RPM hw.sensors.acpithinkpad0.indicator0=Off (port replicator), UNKNOWN This diff checks whether the TMP[0-8] node actually exists during attach and if not, it doesn't create the sensor. It also checks the return value during polling and sets the sensor to invalid if it failed for some reason. hw.sensors.acpithinkpad0.temp0=55.00 degC hw.sensors.acpithinkpad0.fan0=5045 RPM hw.sensors.acpithinkpad0.indicator0=Off (port replicator), UNKNOWN Index: sys/dev/acpi/acpithinkpad.c === RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.70 diff -u -p -u -p -r1.70 acpithinkpad.c --- sys/dev/acpi/acpithinkpad.c 6 Apr 2022 18:59:27 - 1.70 +++ sys/dev/acpi/acpithinkpad.c 5 Apr 2023 03:43:59 - @@ -112,11 +112,10 @@ #defineTHINKPAD_TABLET_SCREEN_CHANGED 0x60c0 #defineTHINKPAD_SWITCH_WIRELESS0x7000 -#define THINKPAD_NSENSORS 10 -#define THINKPAD_NTEMPSENSORS 8 - -#define THINKPAD_SENSOR_FANRPM THINKPAD_NTEMPSENSORS -#define THINKPAD_SENSOR_PORTREPL THINKPAD_NTEMPSENSORS + 1 +#define THINKPAD_SENSOR_FANRPM 0 +#define THINKPAD_SENSOR_PORTREPL 1 +#define THINKPAD_SENSOR_TMP0 2 +#define THINKPAD_NSENSORS 10 #define THINKPAD_ECOFFSET_VOLUME 0x30 #define THINKPAD_ECOFFSET_VOLUME_MUTE_MASK 0x40 @@ -140,6 +139,7 @@ struct acpithinkpad_softc { struct ksensor sc_sens[THINKPAD_NSENSORS]; struct ksensordevsc_sensdev; + int sc_ntempsens; uint64_t sc_hkey_version; @@ -178,6 +178,7 @@ int thinkpad_get_brightness(struct acpit intthinkpad_set_brightness(void *, int); intthinkpad_get_param(struct wsdisplay_param *); intthinkpad_set_param(struct wsdisplay_param *); +intthinkpad_get_temp(struct acpithinkpad_softc *, int, int64_t *); voidthinkpad_sensor_attach(struct acpithinkpad_softc *sc); voidthinkpad_sensor_refresh(void *); @@ -228,6 +229,7 @@ thinkpad_match(struct device *parent, vo void thinkpad_sensor_attach(struct acpithinkpad_softc *sc) { + int64_t tmp; int i; if (sc->sc_acpi->sc_ec == NULL) @@ -237,10 +239,16 @@ thinkpad_sensor_attach(struct acpithinkp /* Add temperature probes */ strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), sizeof(sc->sc_sensdev.xname)); - for (i=0; isc_sens[i].type = SENSOR_TEMP; - sensor_attach(&sc->sc_sensdev, &sc->sc_sens[i]); - } + sc->sc_ntempsens = 0; + for (i = 0; i < THINKPAD_NSENSORS - THINKPAD_SENSOR_TMP0; i++) { + if (thinkpad_get_temp(sc, i, &tmp) != 0) + break; + + sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].type = SENSOR_TEMP; + sensor_attach(&sc->sc_sensdev, + &sc->sc_sens[THINKPAD_SENSOR_TMP0 + i]); + sc->sc_ntempsens++; + } /* Add fan probe */ sc->sc_sens[THINKPAD_SENSOR_FANRPM].type = SENSOR_FANRPM; @@ -262,17 +270,19 @@ thinkpad_sensor_refresh(void *arg) struct acpithinkpad_softc *sc = arg; uint8_t lo, hi, i; int64_t tmp; - char sname[5]; /* Refresh sensor readings */ - for (i=0; isc_acpi, sc->sc_ec->sc_devnode, - sname, 0, 0, &tmp); - sc->sc_sens[i].value = (tmp * 100) + 27315; - if (tmp > 127 || tmp < -127) - sc->sc_sens[i].flags = SENSOR_FINVALID; - } + for (i = 0; i < sc->sc_ntempsens; i++) { + if (thinkpad_get_temp(sc, i, &tmp) != 0) { + sc->sc_sens[i].flags = SENSOR_FINVALID; + continue; + } + + sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].value = + (tmp * 100) + 27315; + sc->sc_sens[THINKPAD_SENSOR_TMP0 + i].flags = + (tmp > 127 || tmp < -127) ? SENSOR_FINVALID : 0; + } /* Read fan RPM */ acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANLO, 1, &lo); @@ -321,10 +331,8 @@ thinkpad_attach(struct device *parent, s wskbd_set_backlight = thinkpad_set_kbd_backlight; } - /* On version 2 and newer, let *drm or acpivout contr
Re: ssh nits
On Thu, 09 Mar 2023 at 06:41:50 +1100, Darren Tucker wrote: > > + if ((negate = (attrib[0] == '!'))) > > This seems to be one too many parens? ie > if (negate = (attrib[0] == '!')) clang warns if there's not the extra set of parens in case it's an accidental = instead of ==. /usr/src/usr.bin/ssh/ssh/../readconf.c:605:14: warning: using the result of an assignment as a condition without parentheses [-Wparentheses] if (negate = (attrib[0] == '!'))
ssh nits
cppcheck found these, are they worth fixing? In the non-fail case, done is set to NULL and then free()d. free(NULL) is legal but maybe worth removing? diff --git usr.bin/ssh/scp.c usr.bin/ssh/scp.c index f0f09bba623..acb7bd8a8a1 100644 --- usr.bin/ssh/scp.c +++ usr.bin/ssh/scp.c @@ -935,19 +935,21 @@ brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp) *npatternsp = ndone; done = NULL; ndone = 0; ret = 0; fail: for (i = 0; i < nactive; i++) free(active[i]); free(active); - for (i = 0; i < ndone; i++) - free(done[i]); - free(done); + if (done) { + for (i = 0; i < ndone; i++) + free(done[i]); + free(done); + } return ret; } static struct sftp_conn * do_sftp_connect(char *host, char *user, int port, char *sftp_direct, int *reminp, int *remoutp, int *pidp) { if (sftp_direct == NULL) { grp == NULL fatal()s, so remove the ternary operations that will never be the conditionals they aspire to be. diff --git usr.bin/ssh/sshpty.c usr.bin/ssh/sshpty.c index faf8960cfb5..690263a8cf3 100644 --- usr.bin/ssh/sshpty.c +++ usr.bin/ssh/sshpty.c @@ -143,8 +143,8 @@ pty_setowner(struct passwd *pw, const char *tty) grp = getgrnam("tty"); if (grp == NULL) fatal("no tty group"); - gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid; - mode = (grp != NULL) ? 0620 : 0600; + gid = grp->gr_gid; + mode = 0620; /* * Change owner and mode of the tty as required. These parentheses checking the result of an assignment were confusing, so move them. diff --git usr.bin/ssh/authfd.c usr.bin/ssh/authfd.c index 4b81b385637..05011f8c5c9 100644 --- usr.bin/ssh/authfd.c +++ usr.bin/ssh/authfd.c @@ -489,8 +489,8 @@ encode_dest_constraint(struct sshbuf *m, const struct dest_constraint *dc) if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; - if ((r = encode_dest_constraint_hop(b, &dc->from) != 0) || - (r = encode_dest_constraint_hop(b, &dc->to) != 0) || + if ((r = encode_dest_constraint_hop(b, &dc->from)) != 0 || + (r = encode_dest_constraint_hop(b, &dc->to)) != 0 || (r = sshbuf_put_string(b, NULL, 0)) != 0) /* reserved */ goto out; if ((r = sshbuf_put_stringb(m, b)) != 0) diff --git usr.bin/ssh/readconf.c usr.bin/ssh/readconf.c index e9d3a756896..81456c9b6d3 100644 --- usr.bin/ssh/readconf.c +++ usr.bin/ssh/readconf.c @@ -602,7 +602,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, } arg = criteria = NULL; this_result = 1; - if ((negate = attrib[0] == '!')) + if ((negate = (attrib[0] == '!'))) attrib++; /* Criterion "all" has no argument and must appear alone */ if (strcasecmp(attrib, "all") == 0) { diff --git usr.bin/ssh/ssh-agent.c usr.bin/ssh/ssh-agent.c index 0e4d7f675ab..de1cdb049a2 100644 --- usr.bin/ssh/ssh-agent.c +++ usr.bin/ssh/ssh-agent.c @@ -1010,8 +1010,8 @@ parse_dest_constraint(struct sshbuf *m, struct dest_constraint *dc) error_fr(r, "parse"); goto out; } - if ((r = parse_dest_constraint_hop(frombuf, &dc->from) != 0) || - (r = parse_dest_constraint_hop(tobuf, &dc->to) != 0)) + if ((r = parse_dest_constraint_hop(frombuf, &dc->from)) != 0 || + (r = parse_dest_constraint_hop(tobuf, &dc->to)) != 0) goto out; /* already logged */ if (elen != 0) { error_f("unsupported extensions (len %zu)", elen);
Re: wsmouse(4): multi-touch buttons again
On Thu, 23 Feb 2023 at 17:05:53 +0100, Tobias Heider wrote: > Wow, thank you for looking into this! I've used your version for a few days > now and it works really well for me (on a m2 macbook air). I actually think > the default works so well that we can default to 0 for param 143. > > IMO we can add it to the tree at this point to give others the change to > test it before the diff gets even bigger. But please add properly named knobs to wsconsctl for this first, and preferably for all of the other hidden settings that were added with wstpad. Expecting users to enable, let alone find, "mouse.tp.param=72:1" is ridiculous. On one of my laptops I wanted to disable the middle soft button and had to dig through the code to figure out that I had to use "wsconsctl mouse.tp.param=65:0".
acpithinkpad: revert 1.67
Revision 1.67 made acpithinkpad not take over screen backlight control and let inteldrm or some other driver handle it. This was done to support fine-grained levels of backlight control rather than the dozen steps that the native EC interface supports. Unfortunately this has the drawback of the EC getting confused about what the backlight level actually is and it still tries to change the backlight automatically in response to Fn+F# keys or plug/unplug events. Notably if you have the laptop plugged in with a backlight value of something high, then unplug it and later lower it with xbacklight, when you plug it back in, the EC automatically adjusts the backlight up to that high value. I don't know how to tell the EC to stop adjusting the backlight automatically on power changes, so I would like to revert this change and go back to only having native EC-controlled backlight with xbacklight or wsconsctl. patrick@ confirmed that he can still change backlight values on the ThinkPad X395 with this backed out, even though part of the reason for this initial change was to help that machine. Index: acpithinkpad.c === RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.70 diff -u -p -u -p -r1.70 acpithinkpad.c --- acpithinkpad.c 6 Apr 2022 18:59:27 - 1.70 +++ acpithinkpad.c 17 Feb 2023 14:41:26 - @@ -321,10 +321,8 @@ thinkpad_attach(struct device *parent, s wskbd_set_backlight = thinkpad_set_kbd_backlight; } - /* On version 2 and newer, let *drm or acpivout control brightness */ - if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION1 && - (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", - 0, NULL, &sc->sc_brightness) == 0)) { + if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", + 0, NULL, &sc->sc_brightness) == 0) { ws_get_param = thinkpad_get_param; ws_set_param = thinkpad_set_param; }
Re: pf max-src-{states,conn} without overload/flush useless?
On Thu, 09 Feb 2023 at 11:51:19 +0100, Alexandr Nedvedicky wrote: > I gave it a try after doing a sysupgrade to: > > penBSD 7.2-current (GENERIC.MP) #1025: Wed Feb 8 19:16:09 MST 2023 > > it still works for me as expected: > disk$ for i in `seq 5` ; do nc 192.168.2.175 22 & done > [1] 51566 > [2] 78983 > [3] 77864 > [4] 37474 > [5] 98599 > disk$ SSH-2.0-OpenSSH_9.2 > SSH-2.0-OpenSSH_9.2 > SSH-2.0-OpenSSH_9.2 > > my connection arrives over iwn0 interface which is in egress group > so our environments are almost identical. Ok now with the latest snapshot kernel I can no longer reproduce this. Maybe there was something unrelated in that snapshot that was causing it. I would still like to have it not fully open the new connection when the max-src-* limit is reached rather than opening and closing, but I guess that is a separate discussion to be had. Thanks for looking into it though.
Re: pf max-src-{states,conn} without overload/flush useless?
On Thu, 09 Feb 2023 at 02:42:22 +0100, Alexandr Nedvedicky wrote: > this is my test terminal on remote host: > router$ for i in `seq 5` ; do nc 192.168.2.175 22 & done > [1] 32472 > [2] 97453 > [3] 7192 > [4] 50386 > [5] 57517 > router$ SSH-2.0-OpenSSH_9.1 > SSH-2.0-OpenSSH_9.1 > SSH-2.0-OpenSSH_9.1 > > there are three SSH version strings which indicates > I got 3 working connection of 5 attempts. Interesting, I tried with your SSH example and it allowed me to connect 5 times. $ for i in `seq 5` ; do nc 192.168.1.240 22 & done [2] 68892 [3] 6303 [4] 63554 [5] 87833 [6] 49997 $ SSH-2.0-OpenSSH_9.1 SSH-2.0-OpenSSH_9.1 SSH-2.0-OpenSSH_9.1 SSH-2.0-OpenSSH_9.1 SSH-2.0-OpenSSH_9.1 vm:~$ doas pfctl -sr block return all pass out all flags S/SA pass in on egress inet6 proto tcp from any to ::1 port = 22 flags S/SA keep state (source-track rule, max-src-conn 3) pass in on egress inet proto tcp from any to 127.0.0.1 port = 22 flags S/SA keep state (source-track rule, max-src-conn 3) pass in on egress inet proto tcp from any to 192.168.1.240 port = 22 flags S/SA keep state (source-track rule, max-src-conn 3) This is with: OpenBSD 7.2-current (GENERIC.MP) #2014: Tue Feb 7 16:24:04 MST 2023 dera...@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP > > diff --git sys/net/pf.c sys/net/pf.c > > index 8cb1326a160..89703feab12 100644 > > --- sys/net/pf.c > > +++ sys/net/pf.c > > @@ -481,12 +481,10 @@ pf_src_connlimit(struct pf_state **stp) > > if ((sn = pf_get_src_node((*stp), PF_SN_NONE)) == NULL) > > return (0); > > > > - sn->conn++; > > - (*stp)->src.tcp_est = 1; > > pf_add_threshold(&sn->conn_rate); > > > > if ((*stp)->rule.ptr->max_src_conn && > > - (*stp)->rule.ptr->max_src_conn < sn->conn) { > > + sn->conn >= (*stp)->rule.ptr->max_src_conn) { > > pf_status.lcounters[LCNT_SRCCONN]++; > > bad++; > > } > > @@ -497,8 +495,11 @@ pf_src_connlimit(struct pf_state **stp) > > bad++; > > } > > > > - if (!bad) > > + if (!bad) { > > + sn->conn++; > > + (*stp)->src.tcp_est = 1; > > return (0); > > + } > > > > if ((*stp)->rule.ptr->overload_tbl) { > > struct pfr_addr p; > > it seems to me the change to pf_src_connlimit() does > not alter behavior. I think change to pf_src_connlimit() > can be dropped. But don't we not want to increment the source node's connection count since we're not going to accept the connection (in the !bad case)? I'm not sure what kind of bookkeeping that would screw up. > > @@ -4919,14 +4920,14 @@ pf_tcp_track_full(struct pf_pdesc *pd, struct > > pf_state **stp, u_short *reason, > > pf_set_protostate(*stp, psrc, TCPS_CLOSING); > > if (th->th_flags & TH_ACK) { > > if (dst->state == TCPS_SYN_SENT) { > > - pf_set_protostate(*stp, pdst, > > - TCPS_ESTABLISHED); > > - if (src->state == TCPS_ESTABLISHED && > > + if (src->state == TCPS_SYN_SENT && > > !SLIST_EMPTY(&(*stp)->src_nodes) && > > pf_src_connlimit(stp)) { > > REASON_SET(reason, PFRES_SRCLIMIT); > > return (PF_DROP); > > } > > + pf_set_protostate(*stp, pdst, > > + TCPS_ESTABLISHED); > > } else if (dst->state == TCPS_CLOSING) > > pf_set_protostate(*stp, pdst, > > TCPS_FIN_WAIT_2); > > > > If I understand things right then in current pf we check conn limit > when we see acknowledgment of 3rd client's ACK sent by server. Not sure > if I sound clear here so let me draw little diagram: > > SYN > sent by client moves state to > > TCPS_SYN_SENT : TCPS_LISTEN/TCPS_CLOSED (1) > > SYN | ACK < sent by server moves state to > > TCPS_SYN_SENT : TCPS_SYN_SENT (2) > > ACK > 3rd ack sent by client move state to: > > TCPS_ESTABLISHED : TCPS_SYN_SENT (3) > > ACK < server acknowledges client's 3rd ack moves state to > > TCPS_ESTABLISHED : TCPS_ESTABLISHED (4) > > currently we do conn limit check in step (4). Your change moves this > to earlier step (3) (given I understand things right here). > It's awfully early here I need sleep on this. Yes, that was my understanding too. We wait until the remote has done enough work to be a valid connection but then block it before sending the final ack. > can you give it a try with your slightly modified diff? just drop > changes to pf_src_connlimit() and keep those in pf_tcp_track_full() which > I believe is the only
pf max-src-{states,conn} without overload/flush useless?
I want to limit incoming connections on a server to 5 per IP. I don't want to put violators into a pf table (overload) or kill the other connections (flush), I just want to not accept new connections from that IP once their limit is reached and then accept them again when they are under the limit. Is this broken or am I holding it wrong? With a simple pf.conf on the server specifying max-src-conn of 5: set skip on lo block return pass out pass in on egress proto tcp to port 80 keep state \ (source-track rule, max-src-conn 5) Run a dumb webserver that prints the pf states on each new connection, and sleeps for a while before responding to keep the connection open: $ doas ruby require "webrick" server = WEBrick::HTTPServer.new(:Port => 80) server.mount_proc "/" do |req, res| puts "states for #{req.remote_ip}:" system "pfctl -ss | grep ' #{req.remote_ip}.*ESTABLISHED'" sleep 30 end trap "INT" do server.shutdown end server.start ^D Now from another machine (192.168.1.196 in this case) send 20 requests at once to the server (192.168.1.240): $ for f in `jot 20`; do ftp -o - http://192.168.1.240/ &; sleep 0.5; done And on the server, you can see that there are now many more than 5 established states: states for 192.168.1.196: all tcp 192.168.1.240:80 <- 192.168.1.196:16727 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 <- 192.168.1.196:24725 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 <- 192.168.1.196:2436 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 <- 192.168.1.196:16529 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 <- 192.168.1.196:4323 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:45576 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:36693 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:2976 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:9395 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:46616 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:46122 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:22969 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:48742 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:43477 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:29154 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:1876 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:47743 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:43833 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:12074 ESTABLISHED:ESTABLISHED all tcp 192.168.1.240:80 -> 192.168.1.196:17816 ESTABLISHED:SYN_SENT Looking at pf.c, the logic in pf_tcp_track_full seems to indicate that it's accepting the connection (moving it to TCPS_ESTABLISHED), then checking pf_src_connlimit, but the PF_DROP gets ignored because the connection is already established. Shouldn't it not accept the connection if pf_src_connlimit returns 1? This does that: diff --git sys/net/pf.c sys/net/pf.c index 8cb1326a160..89703feab12 100644 --- sys/net/pf.c +++ sys/net/pf.c @@ -481,12 +481,10 @@ pf_src_connlimit(struct pf_state **stp) if ((sn = pf_get_src_node((*stp), PF_SN_NONE)) == NULL) return (0); - sn->conn++; - (*stp)->src.tcp_est = 1; pf_add_threshold(&sn->conn_rate); if ((*stp)->rule.ptr->max_src_conn && - (*stp)->rule.ptr->max_src_conn < sn->conn) { + sn->conn >= (*stp)->rule.ptr->max_src_conn) { pf_status.lcounters[LCNT_SRCCONN]++; bad++; } @@ -497,8 +495,11 @@ pf_src_connlimit(struct pf_state **stp) bad++; } - if (!bad) + if (!bad) { + sn->conn++; + (*stp)->src.tcp_est = 1; return (0); + } if ((*stp)->rule.ptr->overload_tbl) { struct pfr_addr p; @@ -4919,14 +4920,14 @@ pf_tcp_track_full(struct pf_pdesc *pd, struct pf_state **stp, u_short *reason, pf_set_protostate(*stp, psrc, TCPS_CLOSING); if (th->th_flags & TH_ACK) { if (dst->state == TCPS_SYN_SENT) { - pf_set_protostate(*stp, pdst, - TCPS_ESTABLISHED); - if (src->state == TCPS_ESTABLISHED && + if (src->state == TCPS_SYN_SENT && !SLIST_EMPTY(&(*stp)->src_nodes) && pf_src_connlimit(stp)) { REASON_SET(reason, PFRES_SRCLIMIT); return (PF_DROP);
remove APM_IOC_NEXTEVENT mentions
The APM_IOC_NEXTEVENT ioctl was ripped out from i386 in 2001 in favor of a kqueue interface, but apm.4 on various arches still claim it's supported or may be in the future which is unlikely. https://github.com/openbsd/src/commit/1e8a3e096b6ef01dcdf4f881eac1b86b1bafe06d Index: share/man/man4/man4.amd64/apm.4 === RCS file: /cvs/src/share/man/man4/man4.amd64/apm.4,v retrieving revision 1.9 diff -u -p -u -p -r1.9 apm.4 --- share/man/man4/man4.amd64/apm.4 31 Mar 2022 17:27:21 - 1.9 +++ share/man/man4/man4.amd64/apm.4 30 Jan 2023 05:01:25 - @@ -103,44 +103,6 @@ The .Va minutes_left value contains the estimated number of minutes of battery life remaining. -.It Dv APM_IOC_NEXTEVENT -.Pq Li "struct apm_event_info" -The APM driver stores up to -.Dv APM_NEVENTS -events. -This was defined as 16 at the time this documentation was written. -If the event list is full when a new event is detected, the new event is lost. -.Dv APM_IOC_NEXTEVENT -ioctl returns the next event on the list or -.Er EAGAIN -if the event list is empty. -The format of the returned event is: -.Bd -literal -offset indent -struct apm_event_info { - u_int type; - u_int index; - u_int spare[8]; -}; -.Ed -where -.Va index -is a sequential count of events that can be used to check if any -events were lost and -.Va type -is one of: -.Bl -tag -width Ds -offset indent -compact -.It Dv APM_STANDBY_REQ -.It Dv APM_SUSPEND_REQ -.It Dv APM_NORMAL_RESUME -.It Dv APM_CRIT_RESUME -.It Dv APM_BATTERY_LOW -.It Dv APM_POWER_CHANGE -.It Dv APM_UPDATE_TIME -.It Dv APM_CRIT_SUSPEND_REQ -.It Dv APM_USER_STANDBY_REQ -.It Dv APM_USER_SUSPEND_REQ -.It Dv APM_SYS_STANDBY_RESUME -.El .It Dv APM_IOC_DEV_CTL .Pq Li "struct apm_ctl" Allows an application to directly set the Index: share/man/man4/man4.arm64/apm.4 === RCS file: /cvs/src/share/man/man4/man4.arm64/apm.4,v retrieving revision 1.5 diff -u -p -u -p -r1.5 apm.4 --- share/man/man4/man4.arm64/apm.4 31 Mar 2022 17:27:21 - 1.5 +++ share/man/man4/man4.arm64/apm.4 30 Jan 2023 05:01:25 - @@ -112,44 +112,6 @@ The .Va minutes_left value contains the estimated number of minutes of battery life remaining. -.It Dv APM_IOC_NEXTEVENT -.Pq Li "struct apm_event_info" -The APM driver stores up to -.Dv APM_NEVENTS -events. -This was defined as 16 at the time this documentation was written. -If the event list is full when a new event is detected, the new event is lost. -.Dv APM_IOC_NEXTEVENT -ioctl returns the next event on the list or -.Er EAGAIN -if the event list is empty. -The format of the returned event is: -.Bd -literal -offset indent -struct apm_event_info { - u_int type; - u_int index; - u_int spare[8]; -}; -.Ed -where -.Va index -is a sequential count of events that can be used to check if any -events were lost and -.Va type -is one of: -.Bl -tag -width Ds -offset indent -compact -.It Dv APM_STANDBY_REQ -.It Dv APM_SUSPEND_REQ -.It Dv APM_NORMAL_RESUME -.It Dv APM_CRIT_RESUME -.It Dv APM_BATTERY_LOW -.It Dv APM_POWER_CHANGE -.It Dv APM_UPDATE_TIME -.It Dv APM_CRIT_SUSPEND_REQ -.It Dv APM_USER_STANDBY_REQ -.It Dv APM_USER_SUSPEND_REQ -.It Dv APM_SYS_STANDBY_RESUME -.El .It Dv APM_IOC_DEV_CTL .Em NOT YET SUPPORTED on arm64 . .Pp Index: share/man/man4/man4.i386/apm.4 === RCS file: /cvs/src/share/man/man4/man4.i386/apm.4,v retrieving revision 1.35 diff -u -p -u -p -r1.35 apm.4 --- share/man/man4/man4.i386/apm.4 31 Mar 2022 17:27:21 - 1.35 +++ share/man/man4/man4.i386/apm.4 30 Jan 2023 05:01:25 - @@ -137,44 +137,6 @@ The .Va minutes_left value contains the estimated number of minutes of battery life remaining. -.It Dv APM_IOC_NEXTEVENT -.Pq Li "struct apm_event_info" -The APM driver stores up to -.Dv APM_NEVENTS -events. -This was defined as 16 at the time this documentation was written. -If the event list is full when a new event is detected, the new event is lost. -.Dv APM_IOC_NEXTEVENT -ioctl returns the next event on the list or -.Er EAGAIN -if the event list is empty. -The format of the returned event is: -.Bd -literal -offset indent -struct apm_event_info { - u_int type; - u_int index; - u_int spare[8]; -}; -.Ed -where -.Va index -is a sequential count of events that can be used to check if any -events were lost and -.Va type -is one of: -.Bl -tag -width Ds -offset indent -compact -.It Dv APM_STANDBY_REQ -.It Dv APM_SUSPEND_REQ -.It Dv APM_NORMAL_RESUME -.It Dv APM_CRIT_RESUME -.It Dv APM_BATTERY_LOW -.It Dv APM_POWER_CHANGE -.It Dv APM_UPDATE_TIME -.It Dv APM_CRIT_SUSPEND_REQ -.It Dv APM_USER_STANDBY_REQ -.It Dv APM_USER_SUSPEND_REQ -.It Dv APM_SYS_STANDBY_RESUME -.El .It Dv APM_IOC_DEV_CTL .Pq Li "struct apm_ctl" Allows an application to directly set the Index: share/man/man4/man4.loongson/apm.4 ===
Re: hidmt: default to clickpad unless report says otherwise
On Fri, 20 May 2022 at 16:46:01 +0200, Ulf Brosziewski wrote: > Shouldn't the check of the button page remain in place, for identifying > plain old touchpads with external buttons? The device in question reports it has multiple buttons when it's just a clickpad, so keeping that check would defeat the purpose of this change. I suppose this diff is not worth it. I guess a hardware-specific quirk can be added for the Framework, or just a wsconsctl knob to turn on the soft button stuff for devices that are detected as touchpads instead of clickpads.
hidmt: default to clickpad unless report says otherwise
Most Windows Precision Touchpad-style touchpads will be clickpads, with no-button "pressure pad" style devices being the outlier. Make clickpad the default unless the report says otherwise. This fixes the Framework laptop which has a PixArt touchpad with a weird HID descriptor report which puts the button type on its own report (so this heuristic doesn't find it) but also claims to have 3 buttons, failing the second heuristic. If it's not setup as a clickpad, wstpad doesn't do left/center/right button emulation properly. I'm curious if this breaks anyone's laptop, especially those ones with a touchpad that also have a separate row of buttons like some Dells. diff --git sys/dev/hid/hidmt.c sys/dev/hid/hidmt.c index 5ca26899e50..0baf724a9da 100644 --- sys/dev/hid/hidmt.c +++ sys/dev/hid/hidmt.c @@ -149,16 +149,13 @@ hidmt_setup(struct device *self, struct hidmt *mt, void *desc, int dlen) mt->sc_num_contacts = d; } - /* find whether this is a clickpad or not */ + /* a "pressure pad" has no buttons, so wstpad needs to know */ + mt->sc_clickpad = 1; if (hid_locate(desc, dlen, HID_USAGE2(HUP_DIGITIZERS, HUD_BUTTON_TYPE), mt->sc_rep_cap, hid_feature, &cap, NULL)) { d = hid_get_udata(rep, capsize, &cap); - mt->sc_clickpad = (d == 0); - } else { - /* if there's not a 2nd button, this is probably a clickpad */ - if (!hid_locate(desc, dlen, HID_USAGE2(HUP_BUTTON, 2), - mt->sc_rep_input, hid_input, &cap, NULL)) - mt->sc_clickpad = 1; + if (d == 0x1) + mt->sc_clickpad = 0; } /*
DPTF sensors driver
Any interest in this? acpidptfs0 at acpi0: SEN2, sensor "Sensor 2 USB2" acpidptfs1 at acpi0: SEN4, sensor "Sensor 4 Ambience" acpidptfs2 at acpi0: SEN1, sensor "Thermistor CPU SOC" acpidptfs3 at acpi0: SEN3, sensor "Sensor 3 SSD" acpidptfs4 at acpi0: SEN5, sensor "Thermistor USB Type-C" hw.sensors.acpidptfs0.temp0=32.05 degC (Sensor 2 USB2) hw.sensors.acpidptfs1.temp0=26.05 degC (Sensor 4 Ambience) hw.sensors.acpidptfs2.temp0=35.05 degC (Thermistor CPU SOC) hw.sensors.acpidptfs3.temp0=35.05 degC (Sensor 3 SSD) hw.sensors.acpidptfs4.temp0=29.05 degC (Thermistor USB Type-C) commit 959656ab8227367705adc45d73f5b6d47d552ac3 Author: joshua stein Date: Mon Aug 9 12:45:15 2021 -0500 acpidptfs: Add a driver for Dynamic Platform and Thermal Framework sensors diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC index ecbf4d82305..3fc30b1e941 100644 --- sys/arch/amd64/conf/GENERIC +++ sys/arch/amd64/conf/GENERIC @@ -85,6 +85,7 @@ acpihid* at acpi? ipmi0 at acpi? disable ccpmic*at iic? tipmic*at iic? +acpidptfs* at acpi? mpbios0at bios0 diff --git sys/dev/acpi/acpidptfs.c sys/dev/acpi/acpidptfs.c new file mode 100644 index 000..c863c8d1f97 --- /dev/null +++ sys/dev/acpi/acpidptfs.c @@ -0,0 +1,173 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2021 joshua stein + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +struct acpidptfs_softc { + struct device sc_dev; + + struct acpi_softc *sc_acpi; + struct aml_node *sc_devnode; + + int sc_devtype; + + struct ksensor sc_sensor; + struct ksensordev sc_sensdev; +}; + +#define ACPIDPTFS_TYPE_SENSOR 0x03 +#define ACPIDPTFS_TYPE_CHARGER 0x0B +#define ACPIDPTFS_TYPE_BATTERY 0x0C + +intacpidptfs_match(struct device *, void *, void *); +void acpidptfs_attach(struct device *, struct device *, void *); +void acpidptfs_sensor_add(struct acpidptfs_softc *); +intacpidptfs_notify(struct aml_node *, int, void *); +void acpidptfs_update(struct acpidptfs_softc *); + +struct cfattach acpidptfs_ca = { + sizeof(struct acpidptfs_softc), + acpidptfs_match, + acpidptfs_attach, + NULL, +}; + +struct cfdriver acpidptfs_cd = { + NULL, "acpidptfs", DV_DULL +}; + +const char *acpidptfs_hids[] = { + "INT3403", + "INTC1043", + "INTC1046", + NULL +}; + +int +acpidptfs_match(struct device *parent, void *match, void *aux) +{ + struct acpi_attach_args *aaa = aux; + struct cfdata *cf = match; + + return acpi_matchhids(aaa, acpidptfs_hids, cf->cf_driver->cd_name); +} + +void +acpidptfs_attach(struct device *parent, struct device *self, void *aux) +{ + struct acpidptfs_softc *sc = (struct acpidptfs_softc *)self; + struct acpi_attach_args *aa = aux; + int64_t res; + + sc->sc_acpi = (struct acpi_softc *)parent; + sc->sc_devnode = aa->aaa_node; + sc->sc_devtype = -1; + + printf(": %s", sc->sc_devnode->name); + + if (aml_evalinteger((struct acpi_softc *)parent, aa->aaa_node, + "_TMP", 0, NULL, &res) == 0) + sc->sc_devtype = ACPIDPTFS_TYPE_SENSOR; + else if (aml_evalinteger((struct acpi_softc *)parent, aa->aaa_node, + "PTYP", 0, NULL, &res) == 0) + sc->sc_devtype = res; + + switch (sc->sc_devtype) { + case ACPIDPTFS_TYPE_SENSOR: + acpidptfs_sensor_add(sc); + break; + case ACPIDPTFS_TYPE_CHARGER: + /* TODO */ + printf(", charger\n"); + break; + case ACPIDPTFS_TYPE_BATTERY: + /* TODO */ + printf(", battery\n"); + break; + default: + printf(", unknown type\n"); + return; + } + + aml_register_notify(sc->sc_devnode, aa->aaa_dev, acpidptfs_notify, +
xenodm and login_fbtab
xenodm supports login_fbtab(3) to chown devices but it currently doesn't do anything because /etc/fbtab does not list /dev/ttyC4. It uses the GiveConsole and TakeConsole scripts in /etc/X11/xenodm/ to do this manually, but the file lists are not complete. I would like to remove all of the custom chown/chmod calls in the GiveConsole and TakeConsole scripts and move this into /etc/fbtab by adding /dev/ttyC4 and all of the wskbd* and wsmouse* devices so that wsconsctl from within X11 works. (These wildcards require the just-committed changes to libutil.) The current fbtab lists many of these devices for /dev/ttyC0 which seems only relevant for running OpenGL applications from the console (is this even possible?) or running X11 as an unprivileged user which we don't support anymore. Is there any particular reason to keep these around for /dev/ttyC0? This has bit me before when I am logged into X11 as my normal user, I login to ttyC0 as root to check something which chowns all the devices to root, then later in X11 I notice no GL-using apps like Firefox work anymore because they can't open /dev/dri nodes. Once these file lists are ironed out, I will make diffs for all the other arches. diff --git etc/etc.amd64/fbtab etc/etc.amd64/fbtab index aec447931a7..df5a7a29cdd 100644 --- etc/etc.amd64/fbtab +++ etc/etc.amd64/fbtab @@ -1 +1,2 @@ -/dev/ttyC0 0600 /dev/console:/dev/wskbd:/dev/wskbd0:/dev/wsmouse:/dev/wsmouse0:/dev/ttyCcfg:/dev/ttyC4:/dev/dri/card0:/dev/dri/renderD128 +/dev/ttyC0 0600/dev/console:/dev/wskbd*:/dev/wsmouse*:/dev/ttyCcfg +/dev/ttyC4 0600 /dev/console:/dev/wskbd*:/dev/wsmouse*:/dev/ttyCcfg:/dev/ttyC4:/dev/dri/*
Re: login_fbtab glob
On Fri, 15 Apr 2022 at 18:54:49 -0600, Todd C. Miller wrote: > On Fri, 15 Apr 2022 13:28:33 -0500, joshua stein wrote: > > > Anyone want to bikeshed this language? > > I think it is more helpful to refer to glob(7) than glob(3). > Perhaps something like this. I like it. Here's the full diff: Index: lib/libutil/login_fbtab.c === RCS file: /cvs/src/lib/libutil/login_fbtab.c,v retrieving revision 1.16 diff -u -p -u -p -r1.16 login_fbtab.c --- lib/libutil/login_fbtab.c 27 Nov 2015 01:57:59 - 1.16 +++ lib/libutil/login_fbtab.c 20 Apr 2022 14:17:08 - @@ -61,8 +61,8 @@ #include #include -#include #include +#include #include #include #include @@ -134,49 +134,31 @@ login_fbtab(const char *tty, uid_t uid, static void login_protect(const char *path, mode_t mask, uid_t uid, gid_t gid) { - charbuf[PATH_MAX]; - size_t pathlen = strlen(path); - DIR *dir; - struct dirent *ent; + glob_t g; + size_t n; + char*gpath; - if (pathlen >= sizeof(buf)) { + if (strlen(path) >= PATH_MAX) { errno = ENAMETOOLONG; syslog(LOG_ERR, "%s: %s: %m", _PATH_FBTAB, path); return; } - if (strcmp("/*", path + pathlen - 2) != 0) { - if (chmod(path, mask) && errno != ENOENT) - syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, path); - if (chown(path, uid, gid) && errno != ENOENT) - syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, path); - } else { - /* -* This is a wildcard directory (/path/to/whatever/ * ). -* Make a copy of path without the trailing '*' (but leave -* the trailing '/' so we can append directory entries.) -*/ - memcpy(buf, path, pathlen - 1); - buf[pathlen - 1] = '\0'; - if ((dir = opendir(buf)) == NULL) { - syslog(LOG_ERR, "%s: opendir(%s): %m", _PATH_FBTAB, - path); - return; - } + if (glob(path, GLOB_NOSORT, NULL, &g) != 0) { + if (errno != ENOENT) + syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path); + globfree(&g); + return; + } - while ((ent = readdir(dir)) != NULL) { - if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0) { - buf[pathlen - 1] = '\0'; - if (strlcat(buf, ent->d_name, sizeof(buf)) - >= sizeof(buf)) { - errno = ENAMETOOLONG; - syslog(LOG_ERR, "%s: %s: %m", - _PATH_FBTAB, path); - } else - login_protect(buf, mask, uid, gid); - } - } - closedir(dir); + for (n = 0; n < g.gl_matchc; n++) { + gpath = g.gl_pathv[n]; + + if (chmod(gpath, mask) && errno != ENOENT) + syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, gpath); + if (chown(gpath, uid, gid) && errno != ENOENT) + syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, gpath); } + + globfree(&g); } Index: share/man/man5/fbtab.5 === RCS file: /cvs/src/share/man/man5/fbtab.5,v retrieving revision 1.14 diff -u -p -u -p -r1.14 fbtab.5 --- share/man/man5/fbtab.5 8 Sep 2014 01:27:55 - 1.14 +++ share/man/man5/fbtab.5 20 Apr 2022 14:17:08 - @@ -51,15 +51,11 @@ An octal permission number (0600), as us .It Other devices The final field is a colon .Pq Ql \&: -delimited list of devices (e.g., -.Dq /dev/console:/dev/fd0a ) . -All device names are absolute paths. -A path that ends in -.Dq /\&* -refers to all directory entries except -.Dq \&. -and -.Dq \&.\&. . +delimited list of device paths (e.g., +.Dq /dev/console:/dev/fd0a:/dev/wskbd* ) . +Device paths may include shell-style globbing patterns (see +.Xr glob 7 ) , +potentially matching multiple devices. .El .Pp The @@ -84,5 +80,6 @@ the files once again belonging to root. .Xr login 1 , .Xr login_fbtab 3 , .Xr init 8 +.Xr glob 7 .Sh AUTHORS .An Guido van Rooij
Re: login_fbtab glob
On Fri, 15 Apr 2022 at 12:17:12 -0600, Todd C. Miller wrote: > On Fri, 15 Apr 2022 13:12:03 -0500, joshua stein wrote: > > > Thanks, both applied. > > Looks good to me but needs a man page update. Anyone want to bikeshed this language? diff --git share/man/man5/fbtab.5 share/man/man5/fbtab.5 index 13dfb634b67..18eade1fbfa 100644 --- share/man/man5/fbtab.5 +++ share/man/man5/fbtab.5 @@ -51,15 +51,11 @@ An octal permission number (0600), as used by .It Other devices The final field is a colon .Pq Ql \&: -delimited list of devices (e.g., -.Dq /dev/console:/dev/fd0a ) . -All device names are absolute paths. -A path that ends in -.Dq /\&* -refers to all directory entries except -.Dq \&. -and -.Dq \&.\&. . +delimited list of device paths (e.g., +.Dq /dev/console:/dev/fd0a:/dev/wskbd* ) . +All device paths are processed through +.Xr glob 3 +to expand any wildcard characters and potentially match multiple devices. .El .Pp The @@ -84,5 +80,6 @@ the files once again belonging to root. .Xr login 1 , .Xr login_fbtab 3 , .Xr init 8 +.Xr glob 3 .Sh AUTHORS .An Guido van Rooij
Re: login_fbtab glob
On Fri, 15 Apr 2022 at 09:32:46 -0600, Todd C. Miller wrote: > On Thu, 14 Apr 2022 17:52:37 -0500, joshua stein wrote: > > > login_fbtab(3) supports wildcards but only for every file in a > > directory (/path/*). > > > > This makes it use glob(3) so it can also support more specific > > wildcards like /path/file* > > Yes, it is better to use glob(3) than something custom. > Comments inline. Thanks, both applied. diff --git lib/libutil/login_fbtab.c lib/libutil/login_fbtab.c index 5eacf4f65ff..b81bc8e38e4 100644 --- lib/libutil/login_fbtab.c +++ lib/libutil/login_fbtab.c @@ -61,8 +61,8 @@ #include #include -#include #include +#include #include #include #include @@ -134,49 +134,31 @@ login_fbtab(const char *tty, uid_t uid, gid_t gid) static void login_protect(const char *path, mode_t mask, uid_t uid, gid_t gid) { - charbuf[PATH_MAX]; - size_t pathlen = strlen(path); - DIR *dir; - struct dirent *ent; + glob_t g; + size_t n; + char*gpath; - if (pathlen >= sizeof(buf)) { + if (strlen(path) >= PATH_MAX) { errno = ENAMETOOLONG; syslog(LOG_ERR, "%s: %s: %m", _PATH_FBTAB, path); return; } - if (strcmp("/*", path + pathlen - 2) != 0) { - if (chmod(path, mask) && errno != ENOENT) - syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, path); - if (chown(path, uid, gid) && errno != ENOENT) - syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, path); - } else { - /* -* This is a wildcard directory (/path/to/whatever/ * ). -* Make a copy of path without the trailing '*' (but leave -* the trailing '/' so we can append directory entries.) -*/ - memcpy(buf, path, pathlen - 1); - buf[pathlen - 1] = '\0'; - if ((dir = opendir(buf)) == NULL) { - syslog(LOG_ERR, "%s: opendir(%s): %m", _PATH_FBTAB, - path); - return; - } + if (glob(path, GLOB_NOSORT, NULL, &g) != 0) { + if (errno != ENOENT) + syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path); + globfree(&g); + return; + } - while ((ent = readdir(dir)) != NULL) { - if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0) { - buf[pathlen - 1] = '\0'; - if (strlcat(buf, ent->d_name, sizeof(buf)) - >= sizeof(buf)) { - errno = ENAMETOOLONG; - syslog(LOG_ERR, "%s: %s: %m", - _PATH_FBTAB, path); - } else - login_protect(buf, mask, uid, gid); - } - } - closedir(dir); + for (n = 0; n < g.gl_matchc; n++) { + gpath = g.gl_pathv[n]; + + if (chmod(gpath, mask) && errno != ENOENT) + syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, gpath); + if (chown(gpath, uid, gid) && errno != ENOENT) + syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, gpath); } + + globfree(&g); }
login_fbtab glob
login_fbtab(3) supports wildcards but only for every file in a directory (/path/*). This makes it use glob(3) so it can also support more specific wildcards like /path/file* diff --git lib/libutil/login_fbtab.c lib/libutil/login_fbtab.c index 5eacf4f65ff..39621a0cde4 100644 --- lib/libutil/login_fbtab.c +++ lib/libutil/login_fbtab.c @@ -61,8 +61,8 @@ #include #include -#include #include +#include #include #include #include @@ -134,49 +134,32 @@ login_fbtab(const char *tty, uid_t uid, gid_t gid) static void login_protect(const char *path, mode_t mask, uid_t uid, gid_t gid) { - charbuf[PATH_MAX]; - size_t pathlen = strlen(path); - DIR *dir; - struct dirent *ent; + glob_t g; + size_t n; + char*gpath; - if (pathlen >= sizeof(buf)) { + if (strlen(path) > PATH_MAX) { errno = ENAMETOOLONG; syslog(LOG_ERR, "%s: %s: %m", _PATH_FBTAB, path); return; } - if (strcmp("/*", path + pathlen - 2) != 0) { - if (chmod(path, mask) && errno != ENOENT) - syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, path); - if (chown(path, uid, gid) && errno != ENOENT) - syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, path); - } else { - /* -* This is a wildcard directory (/path/to/whatever/ * ). -* Make a copy of path without the trailing '*' (but leave -* the trailing '/' so we can append directory entries.) -*/ - memcpy(buf, path, pathlen - 1); - buf[pathlen - 1] = '\0'; - if ((dir = opendir(buf)) == NULL) { - syslog(LOG_ERR, "%s: opendir(%s): %m", _PATH_FBTAB, - path); - return; - } + g.gl_offs = 0; + if (glob(path, GLOB_DOOFFS, NULL, &g) != 0) { + if (errno != ENOENT) + syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path); + globfree(&g); + return; + } - while ((ent = readdir(dir)) != NULL) { - if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0) { - buf[pathlen - 1] = '\0'; - if (strlcat(buf, ent->d_name, sizeof(buf)) - >= sizeof(buf)) { - errno = ENAMETOOLONG; - syslog(LOG_ERR, "%s: %s: %m", - _PATH_FBTAB, path); - } else - login_protect(buf, mask, uid, gid); - } - } - closedir(dir); + for (n = 0; n < g.gl_matchc; n++) { + gpath = g.gl_pathv[n]; + + if (chmod(gpath, mask) && errno != ENOENT) + syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, gpath); + if (chown(gpath, uid, gid) && errno != ENOENT) + syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, gpath); } + + globfree(&g); }
Re: sndiod: -F does not switch back to preferred device
On Thu, 09 Dec 2021 at 16:46:24 -0700, Theo de Raadt wrote: > Please do not recommend people use hotplugd, for any purpose. > > It is on my queue for deletion, because noone has stepped up and > fixed it. > > hotplug is COMPLETELY FLAWED. It reports when a device is attached, > not when it is ready. As a result everyone uses it wrong. > > As a result, your script is broken. There is no assurance that the > audio device's ioctl routines are ready 1ms after subr_autoconf returns > from the xxattach() function. I sent diffs for this in 2018 and nobody wanted them. I wanted multiple reader support on /dev/hotplug for Xorg and you gave this same complaint about hotplug being flawed, so I proposed a simple way for particular drivers to defer their hotplug announcement until they were ready. From 2018: I chatted with Theo about that and I proposed that we just have a way for those specific drivers to tell hotplug to defer their attachment announcement and then they can manually request announcement later when they're ready. However, I just searched the bugs@ archives and all of the mentions of hotplugd were like 8 years ago, and they were all related to USB disks. Then some of the bugs were closed after an apparent change to hotplug.c was made: https://marc.info/?l=openbsd-bugs&m=127990199813627&w=2 After that, I can't find any reports of panics related to using hotplugd. Are we sure this is even a problem anymore? Nobody stepped up with any drivers that actually needed it. Here's the diff from 2018, and another to implement multiple readers on /dev/hotplug so things like sndiod could use it. If anyone actually cares about them this time, I can update them to a current tree. diff --git sys/dev/hotplug.c sys/dev/hotplug.c index fccd5a7c9e3..f75e830 100644 --- sys/dev/hotplug.c +++ sys/dev/hotplug.c @@ -89,6 +89,12 @@ hotplug_device_detach(enum devclass class, char *name) hotplug_put_event(&he); } +void +hotplug_defer_attach(struct device *dev) +{ + dev->dv_flags |= DVF_HOTPLUG_DEFER; +} + void hotplug_put_event(struct hotplug_event *he) { diff --git sys/kern/subr_autoconf.c sys/kern/subr_autoconf.c index 3fff153e8ad..a31ca509e35 100644 --- sys/kern/subr_autoconf.c +++ sys/kern/subr_autoconf.c @@ -401,7 +401,7 @@ config_attach(struct device *parent, void *match, void *aux, cfprint_t print) (*ca->ca_attach)(parent, dev, aux); config_process_deferred_children(dev); #if NHOTPLUG > 0 - if (!cold) + if (!cold && !(dev->dv_flags & DVF_HOTPLUG_DEFER)) hotplug_device_attach(cd->cd_class, dev->dv_xname); #endif diff --git sys/sys/device.h sys/sys/device.h index 1faa0192a99..596ef1a26d5 100644 --- sys/sys/device.h +++ sys/sys/device.h @@ -81,7 +81,8 @@ struct device { }; /* dv_flags */ -#defineDVF_ACTIVE 0x0001 /* device is activated */ +#defineDVF_ACTIVE 0x0001 /* device is activated */ +#defineDVF_HOTPLUG_DEFER 0x0002 /* defer hotplug announce */ TAILQ_HEAD(devicelist, device); diff --git sys/sys/hotplug.h sys/sys/hotplug.h index f2da3f6cfd8..7e68482a428 100644 --- sys/sys/hotplug.h +++ sys/sys/hotplug.h @@ -35,6 +35,7 @@ struct hotplug_event { #ifdef _KERNEL void hotplug_device_attach(enum devclass, char *); void hotplug_device_detach(enum devclass, char *); +void hotplug_defer_attach(struct device *); #endif #endif /* _SYS_HOTPLUG_H_ */ Index: sys/dev/hotplug.c === RCS file: /cvs/src/sys/dev/hotplug.c,v retrieving revision 1.16 diff -u -p -u -p -r1.16 hotplug.c --- sys/dev/hotplug.c 7 Jun 2016 01:31:54 - 1.16 +++ sys/dev/hotplug.c 2 Sep 2018 17:42:50 - @@ -1,5 +1,6 @@ /* $OpenBSD: hotplug.c,v 1.16 2016/06/07 01:31:54 tedu Exp $ */ /* + * Copyright (c) 2018 joshua stein * Copyright (c) 2004 Alexander Yurchenko * * Permission to use, copy, modify, and distribute this software for any @@ -25,15 +26,24 @@ #include #include #include +#include #include #include #define HOTPLUG_MAXEVENTS 64 -static int opened; +struct hotplug_dev { + int hd_unit; + int hd_evqueue_head; + struct selinfo hd_sel; + LIST_ENTRY(hotplug_dev) hd_list; +}; + +LIST_HEAD(, hotplug_dev) hotplug_dev_list; +struct hotplug_dev *hotplug_lookup(int); + static struct hotplug_event evqueue[HOTPLUG_MAXEVENTS]; -static int evqueue_head, evqueue_tail, evqueue_count; -static struct selinfo hotplug_sel; +static int evqueue_head, evqueue_count; void filt_hotplugrdetach(struct knote *); int filt_hotplugread(struct knote *, long); @@ -43,19 +53,18 @@ struct filterops hotplugread_filtops = #define EVQUEUE_NEXT(p) (p == HOTPLUG_MAXEVENTS - 1 ? 0 : p + 1) - -int h
Re: iwx(4) 40MHz channel support
On Thu, 14 Oct 2021 at 09:21:18 +0200, Stefan Hagen wrote: > This ramp up time is reproducible. It always starts slower in the first > 1 or 2 seconds and then ramps up to full speed. I've observed this in ethernet transfers on OpenBSD for a long time, it's not limited to WiFi.
Re: ihidev: fix data request size
On Sun, 22 Aug 2021 at 22:37:51 -0600, Thomas Frohwein wrote: > On Sun, Aug 22, 2021 at 09:50:15PM -0500, joshua stein wrote: > > On a particular laptop with a touchpad behind ihidev, dwiic would > > report a timeout every time it had to fetch touch data: > > > > dwiic0: timed out reading remaining 2 > > > > On re-reading the i2c HID spec, the size supplied by wMaxInputLength > > is already supposed to account for the size and report id bytes so > > we shouldn't be adding them after the fact. Otherwise ihidev would > > ask for more data than can be available and, on this laptop anyway, > > dwiic would have to wait for this transaction to timeout and fail. > > > > This fix matches how the Linux i2c-hid driver operates. I've tested > > this on 3 laptops with touchpads and touchscreens and it doesn't > > cause any regressions here while fixing the touchpad on one of them. > > I'd appreciate tests on other laptops to make sure it doesn't break > > anything and perhaps fixes your issue if you've also seen constant > > dwiic timeouts. > > > > I thought I had the same problem on my new Asus Expertbook B9400CEA. > During boot, while reordering libraries and later it would print: > > dwiic2: timed out reading remaining 16 > > This is accompanied by generalized slowness of the system - boot is > noticeably slow, xenodm takes about 20 seconds to get to the login > window, and glxgears(1) slows down visibly with any mouse movement. That is because dwiic has to use polling while being invoked by ihidev's interrupt handler or else it panics in tsleep. It has to wait longer than normal using delay(), so it blocks other kernel processing. As for why the timeouts are happening in the first place, it could be a similar issue with the max report size being bogus. Does this diff change anything? diff --git sys/dev/i2c/ihidev.c sys/dev/i2c/ihidev.c index 92778c679ad..0baba616329 100644 --- sys/dev/i2c/ihidev.c +++ sys/dev/i2c/ihidev.c @@ -152,7 +152,7 @@ ihidev_attach(struct device *parent, struct device *self, void *aux) } /* find largest report size and allocate memory for input buffer */ - sc->sc_isize = letoh16(sc->hid_desc.wMaxInputLength); + sc->sc_isize = 4; for (repid = 0; repid < sc->sc_nrepid; repid++) { repsz = hid_report_size(sc->sc_report, sc->sc_reportlen, hid_input, repid); @@ -643,7 +643,7 @@ ihidev_intr(void *arg) iic_acquire_bus(sc->sc_tag, I2C_F_POLL); res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, NULL, 0, - sc->sc_ibuf, letoh16(sc->hid_desc.wMaxInputLength), I2C_F_POLL); + sc->sc_ibuf, sc->sc_isize, I2C_F_POLL); iic_release_bus(sc->sc_tag, I2C_F_POLL); /*
ihidev: fix data request size
On a particular laptop with a touchpad behind ihidev, dwiic would report a timeout every time it had to fetch touch data: dwiic0: timed out reading remaining 2 On re-reading the i2c HID spec, the size supplied by wMaxInputLength is already supposed to account for the size and report id bytes so we shouldn't be adding them after the fact. Otherwise ihidev would ask for more data than can be available and, on this laptop anyway, dwiic would have to wait for this transaction to timeout and fail. This fix matches how the Linux i2c-hid driver operates. I've tested this on 3 laptops with touchpads and touchscreens and it doesn't cause any regressions here while fixing the touchpad on one of them. I'd appreciate tests on other laptops to make sure it doesn't break anything and perhaps fixes your issue if you've also seen constant dwiic timeouts. Index: sys/dev/i2c/ihidev.c === RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v retrieving revision 1.23 diff -u -p -u -p -r1.23 ihidev.c --- sys/dev/i2c/ihidev.c9 Jul 2020 21:01:55 - 1.23 +++ sys/dev/i2c/ihidev.c23 Aug 2021 02:38:21 - @@ -106,7 +106,6 @@ ihidev_attach(struct device *parent, str struct device *dev; int repid, repsz; int repsizes[256]; - int isize; sc->sc_tag = ia->ia_tag; sc->sc_addr = ia->ia_addr; @@ -158,12 +157,8 @@ ihidev_attach(struct device *parent, str repsz = hid_report_size(sc->sc_report, sc->sc_reportlen, hid_input, repid); repsizes[repid] = repsz; - - isize = repsz + 2; /* two bytes for the length */ - isize += (sc->sc_nrepid != 1); /* one byte for the report ID */ - if (isize > sc->sc_isize) - sc->sc_isize = isize; - + if (repsz > sc->sc_isize) + sc->sc_isize = repsz; if (repsz != 0) DPRINTF(("%s: repid %d size %d\n", sc->sc_dev.dv_xname, repid, repsz)); @@ -648,7 +643,7 @@ ihidev_intr(void *arg) iic_acquire_bus(sc->sc_tag, I2C_F_POLL); res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, NULL, 0, - sc->sc_ibuf, sc->sc_isize, I2C_F_POLL); + sc->sc_ibuf, letoh16(sc->hid_desc.wMaxInputLength), I2C_F_POLL); iic_release_bus(sc->sc_tag, I2C_F_POLL); /*
Re: ucc(4): consumer control keyboard device driver
On Wed, 18 Aug 2021 at 18:48:45 +0200, Martin Pieuchot wrote: > Regarding the introduction of a separate wskbd(4) this can be seen as an > intermediate step. Having this logic in ukbd(4) implies revisiting the > way reportID are mapped to USB drivers, which is still a bit of a hack > when it comes to supporting multiple of them. Having a simpler driver > like ucc(4) can help us figure out out to support more "special" keys > without having to deal with the HID logic at the same time. > > It would be great if users of usbhidaction(1) could tell us if this > introduce any regression and/or if other keys could be supported. I used usbhidaction for a Bluetooth audio device that supported passing button presses through. https://jcs.org/2020/11/18/openbsd_btaudio#responding-to-headphone-buttons $ cat .usbhidaction.conf Consumer:Play/Pause 1 ~/bin/music playpause Due to the lack of an XF86Audio* keysym that is both "play/pause", ucc can only map it to just XF86AudioPlay. It's no big deal for me to adapt though, and I'm happy to see a driver do all of this automatically. Though it would be nice to find a way to pass any unsupported buttons through, even if they are just no-named keysyms that would at least allow a program to bind/react to them.
Re: usbhidctl: add -R flag to dump raw report descriptor bytes
On Fri, 28 May 2021 at 21:52:57 -0500, joshua stein wrote: > > Another approach which keeps the structure opaque is the extend the > > usbhid(3) API with something like: > > > > void > > hid_get_report_desc_data(report_desc_t d, uint8_t **data, uint32_t > > *size) > > { > > *data = d->data; > > *size = d->size; > > } Here's a new version of the usbhidctl diff using this new usbhid API, with man page help from jmc. diff --git usr.bin/usbhidctl/usbhid.c usr.bin/usbhidctl/usbhid.c index 921f211a280..910263d1392 100644 --- usr.bin/usbhidctl/usbhid.c +++ usr.bin/usbhidctl/usbhid.c @@ -755,6 +755,7 @@ usage(void) fprintf(stderr, " %s -f device [-t table] -w name=value ...\n", __progname); + fprintf(stderr, " %s -f device -R\n", __progname); exit(1); } @@ -764,16 +765,18 @@ main(int argc, char **argv) char const *dev; char const *table; size_t varnum; - int aflag, lflag, nflag, rflag, wflag; - int ch, hidfd; + uint32_t repsize; + int aflag, lflag, nflag, rflag, Rflag, wflag; + int ch, hidfd, x; + uint8_t *repdata; report_desc_t repdesc; char devnamebuf[PATH_MAX]; struct Susbvar variables[128]; - wflag = aflag = nflag = verbose = rflag = lflag = 0; + wflag = aflag = nflag = verbose = rflag = Rflag = lflag = 0; dev = NULL; table = NULL; - while ((ch = getopt(argc, argv, "?af:lnrt:vw")) != -1) { + while ((ch = getopt(argc, argv, "?af:lnRrt:vw")) != -1) { switch (ch) { case 'a': aflag = 1; @@ -790,6 +793,9 @@ main(int argc, char **argv) case 'r': rflag = 1; break; + case 'R': + Rflag = 1; + break; case 't': table = optarg; break; @@ -807,7 +813,8 @@ main(int argc, char **argv) } argc -= optind; argv += optind; - if (dev == NULL || (lflag && (wflag || rflag))) { + if (dev == NULL || (lflag && (wflag || rflag || Rflag)) || + (rflag && Rflag)) { /* * No device specified, or attempting to loop and set * or dump report at the same time @@ -942,6 +949,14 @@ main(int argc, char **argv) if (repdesc == 0) errx(1, "USB_GET_REPORT_DESC"); + if (Rflag) { + hid_get_report_desc_data(repdesc, &repdata, &repsize); + + for (x = 0; x < repsize; x++) + printf("%s0x%02x", x > 0 ? " " : "", repdata[x]); + printf("\n"); + } + if (lflag) { devloop(hidfd, repdesc, variables, varnum); /* NOTREACHED */ @@ -951,10 +966,11 @@ main(int argc, char **argv) /* Report mode header */ printf("Report descriptor:\n"); - devshow(hidfd, repdesc, variables, varnum, - 1 << hid_input | - 1 << hid_output | - 1 << hid_feature); + if (!Rflag) + devshow(hidfd, repdesc, variables, varnum, + 1 << hid_input | + 1 << hid_output | + 1 << hid_feature); if (rflag) { /* Report mode trailer */ diff --git usr.bin/usbhidctl/usbhidctl.1 usr.bin/usbhidctl/usbhidctl.1 index 5b8e59f7bd7..0aa5b54f6f9 100644 --- usr.bin/usbhidctl/usbhidctl.1 +++ usr.bin/usbhidctl/usbhidctl.1 @@ -53,6 +53,9 @@ .Fl f Ar device .Op Fl t Ar table .Fl w Ar name Ns = Ns Ar value ... +.Nm +.Fl f Ar device +.Fl R .Sh DESCRIPTION .Nm can be used to output or modify the state of a USB HID (Human Interface Device). @@ -88,6 +91,8 @@ Only 'input' items are displayed in this mode. .It Fl n Suppress printing of the item name when querying specific items. Only output the current value. +.It Fl R +Dump the raw USB HID report descriptor data as hexadecimal bytes. .It Fl r Dump the USB HID report descriptor. .It Fl t Ar table
Re: usbhidctl: add -R flag to dump raw report descriptor bytes
On Wed, 26 May 2021 at 08:13:52 +0200, Anton Lindqvist wrote: > On Tue, May 25, 2021 at 08:31:14AM +0200, Anton Lindqvist wrote: > > On Mon, May 24, 2021 at 09:17:26AM -0500, joshua stein wrote: > > > This is useful for parsing the report descriptor with a different > > > tool to find issues with our HID parser. > > > > > > I've found https://eleccelerator.com/usbdescreqparser/ to be > > > helpful. > > > > > > > > > diff --git usr.bin/usbhidctl/usbhid.c usr.bin/usbhidctl/usbhid.c > > > index 921f211a280..bd0b5da0222 100644 > > > --- usr.bin/usbhidctl/usbhid.c > > > +++ usr.bin/usbhidctl/usbhid.c > > > @@ -106,6 +106,11 @@ static struct { > > > #define REPORT_MAXVAL 2 > > > }; > > > > > > +struct report_desc { > > > + uint32_t size; > > > + uint8_t data[1]; > > > +}; > > > > This structure is defined in lib/libusbhid/usbvar.h which is not > > installed. Maybe it should and avoid this repetition and potential ABI > > breaks (quite unlikely but still)? > > Another approach which keeps the structure opaque is the extend the > usbhid(3) API with something like: > > void > hid_get_report_desc_data(report_desc_t d, uint8_t **data, uint32_t > *size) > { > *data = d->data; > *size = d->size; > } Here's a version of that: diff --git lib/libusbhid/Makefile lib/libusbhid/Makefile index 2d5a75004ad..be1adde806d 100644 --- lib/libusbhid/Makefile +++ lib/libusbhid/Makefile @@ -9,7 +9,7 @@ SRCS= descr.c parse.c usage.c data.c CPPFLAGS+= -I${.CURDIR} includes: - @cd ${.CURDIR}; cmp -s usbhid.h ${DESTDIR}/usr/include/usbhid.h || \ + cd ${.CURDIR}; cmp -s usbhid.h ${DESTDIR}/usr/include/usbhid.h || \ ${INSTALL} ${INSTALL_COPY} -m 444 -o $(BINOWN) -g $(BINGRP) usbhid.h \ ${DESTDIR}/usr/include diff --git lib/libusbhid/descr.c lib/libusbhid/descr.c index 9d81c2f0e3f..963108f644c 100644 --- lib/libusbhid/descr.c +++ lib/libusbhid/descr.c @@ -71,3 +71,10 @@ hid_dispose_report_desc(report_desc_t r) free(r); } + +void +hid_get_report_desc_data(report_desc_t d, uint8_t **data, uint32_t *size) +{ + *data = d->data; + *size = d->size; +} diff --git lib/libusbhid/usbhid.3 lib/libusbhid/usbhid.3 index 62771a95798..61b2d3fe2a9 100644 --- lib/libusbhid/usbhid.3 +++ lib/libusbhid/usbhid.3 @@ -33,6 +33,7 @@ .Nm hid_get_report_desc , .Nm hid_use_report_desc , .Nm hid_dispose_report_desc , +.Nm hid_get_report_desc_data , .Nm hid_start_parse , .Nm hid_end_parse , .Nm hid_get_item , @@ -55,6 +56,8 @@ .Fn hid_use_report_desc "unsigned char *data" "unsigned int size" .Ft void .Fn hid_dispose_report_desc "report_desc_t d" +.Ft void +.Fn hid_get_report_desc_data "report_desc_t d" "uint8_t **data" "uint32_t *size" .Ft hid_data_t .Fn hid_start_parse "report_desc_t d" "int kindset" "int id" .Ft void @@ -104,7 +107,8 @@ with a file descriptor obtained by opening a device. Alternatively a data buffer containing the report descriptor can be passed into .Fn hid_use_report_desc . -The data is copied into an internal structure. +The data is copied into an internal structure which can be accessed with +.Fn hid_get_report_desc_data . When the report descriptor is no longer needed it should be freed by calling .Fn hid_dispose_report_desc . The type diff --git lib/libusbhid/usbhid.h lib/libusbhid/usbhid.h index 39adb4ad02f..8694c3aea1d 100644 --- lib/libusbhid/usbhid.h +++ lib/libusbhid/usbhid.h @@ -77,6 +77,7 @@ typedef struct hid_item { report_desc_t hid_get_report_desc(int file); report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size); void hid_dispose_report_desc(report_desc_t); +void hid_get_report_desc_data(report_desc_t, uint8_t **, uint32_t *); /* Parsing of a HID report descriptor, parse.c: */ hid_data_t hid_start_parse(report_desc_t d, int kindset, int id);
usbhidctl: add -R flag to dump raw report descriptor bytes
This is useful for parsing the report descriptor with a different tool to find issues with our HID parser. I've found https://eleccelerator.com/usbdescreqparser/ to be helpful. diff --git usr.bin/usbhidctl/usbhid.c usr.bin/usbhidctl/usbhid.c index 921f211a280..bd0b5da0222 100644 --- usr.bin/usbhidctl/usbhid.c +++ usr.bin/usbhidctl/usbhid.c @@ -106,6 +106,11 @@ static struct { #define REPORT_MAXVAL 2 }; +struct report_desc { + uint32_t size; + uint8_t data[1]; +}; + /* * Extract 16-bit unsigned usage ID from a numeric string. Returns -1 * if string failed to parse correctly. @@ -747,7 +752,7 @@ usage(void) fprintf(stderr, "usage: %s -f device [-t table] [-alv]\n", __progname); - fprintf(stderr, " %s -f device [-t table] [-v] -r\n", + fprintf(stderr, " %s -f device [-t table] [-v] [-r|-R]\n", __progname); fprintf(stderr, " %s -f device [-t table] [-lnv] name ...\n", @@ -764,16 +769,16 @@ main(int argc, char **argv) char const *dev; char const *table; size_t varnum; - int aflag, lflag, nflag, rflag, wflag; - int ch, hidfd; + int aflag, lflag, nflag, rflag, Rflag, wflag; + int ch, hidfd, x; report_desc_t repdesc; char devnamebuf[PATH_MAX]; struct Susbvar variables[128]; - wflag = aflag = nflag = verbose = rflag = lflag = 0; + wflag = aflag = nflag = verbose = rflag = Rflag = lflag = 0; dev = NULL; table = NULL; - while ((ch = getopt(argc, argv, "?af:lnrt:vw")) != -1) { + while ((ch = getopt(argc, argv, "?af:lnRrt:vw")) != -1) { switch (ch) { case 'a': aflag = 1; @@ -790,6 +795,9 @@ main(int argc, char **argv) case 'r': rflag = 1; break; + case 'R': + Rflag = 1; + break; case 't': table = optarg; break; @@ -807,7 +815,8 @@ main(int argc, char **argv) } argc -= optind; argv += optind; - if (dev == NULL || (lflag && (wflag || rflag))) { + if (dev == NULL || (lflag && (wflag || rflag || Rflag)) || + (rflag && Rflag)) { /* * No device specified, or attempting to loop and set * or dump report at the same time @@ -942,6 +951,12 @@ main(int argc, char **argv) if (repdesc == 0) errx(1, "USB_GET_REPORT_DESC"); + if (Rflag) { + for (x = 0; x < repdesc->size; x++) + printf("%s0x%02x", x > 0 ? " " : "", repdesc->data[x]); + printf("\n"); + } + if (lflag) { devloop(hidfd, repdesc, variables, varnum); /* NOTREACHED */ @@ -951,10 +966,11 @@ main(int argc, char **argv) /* Report mode header */ printf("Report descriptor:\n"); - devshow(hidfd, repdesc, variables, varnum, - 1 << hid_input | - 1 << hid_output | - 1 << hid_feature); + if (!Rflag) + devshow(hidfd, repdesc, variables, varnum, + 1 << hid_input | + 1 << hid_output | + 1 << hid_feature); if (rflag) { /* Report mode trailer */ diff --git usr.bin/usbhidctl/usbhidctl.1 usr.bin/usbhidctl/usbhidctl.1 index 5b8e59f7bd7..54f5a49270d 100644 --- usr.bin/usbhidctl/usbhidctl.1 +++ usr.bin/usbhidctl/usbhidctl.1 @@ -47,6 +47,11 @@ .Nm .Fl f Ar device .Op Fl t Ar table +.Op Fl v +.Fl R +.Nm +.Fl f Ar device +.Op Fl t Ar table .Op Fl lnv .Ar name ... .Nm @@ -90,6 +95,8 @@ Suppress printing of the item name when querying specific items. Only output the current value. .It Fl r Dump the USB HID report descriptor. +.It Fl R +Dump the USB HID report descriptor as hexadecimal bytes. .It Fl t Ar table Specify a path name for the HID usage table file. .It Fl v
hidms: don't ignore mice with no x/y coordinates
A bug was reported where a Kensington USB trackball didn't work properly: uhidev4 at uhub0 port 6 configuration 1 interface 0 "Kensington Expert Wireless TB" rev 2.00/1.02 addr 9 uhidev4: iclass 3/1, 3 report ids ums3 at uhidev4 reportid 1 ums3: mouse has no X report ums4 at uhidev4 reportid 2: 0 button wsmouse3 at ums4 mux 0 After looking at the HID report descriptor, this device is weird in that it puts the buttons and wheel on one report and the trackball X/Y coordinates an another. This causes uhidev to attach two ums devices, but the first one fails because there are no X/Y reports found. The proper fix is probably to make ums act like umt and use UHIDEV_CLAIM_MULTIPLE_REPORTID to find all of the necessary reports and attach to multiple at once if needed. I started working on this but all of the logic in hidms_setup gets tricky when it has to look at multiple reports. So an easier fix is to just not consider a mouse with no X/Y reports invalid. Now the device attaches to the first button/wheel report: uhidev4 at uhub4 port 4 configuration 1 interface 0 "Kensington Expert Wireless TB" rev 2.00/1.02 addr 3 uhidev4: iclass 3/1, 3 report ids ums1 at uhidev4 reportid 1: 5 buttons, Z and W dir wsmouse1 at ums1 mux 0 ums2 at uhidev4 reportid 2: 0 buttons wsmouse2 at ums2 mux 0 Checking dmesglog for 'no X report' yields a lot of results, so this may help on other devices. diff --git sys/dev/hid/hidms.c sys/dev/hid/hidms.c index ab9cd9c797e..92ca89537da 100644 --- sys/dev/hid/hidms.c +++ sys/dev/hid/hidms.c @@ -76,10 +76,9 @@ hidms_setup(struct device *self, struct hidms *ms, uint32_t quirks, ms->sc_flags = quirks; if (!hid_locate(desc, dlen, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), id, - hid_input, &ms->sc_loc_x, &flags)) { - printf("\n%s: mouse has no X report\n", self->dv_xname); - return ENXIO; - } + hid_input, &ms->sc_loc_x, &flags)) + ms->sc_loc_x.size = 0; + switch(flags & MOUSE_FLAGS_MASK) { case 0: ms->sc_flags |= HIDMS_ABSX; @@ -93,10 +92,9 @@ hidms_setup(struct device *self, struct hidms *ms, uint32_t quirks, } if (!hid_locate(desc, dlen, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), id, - hid_input, &ms->sc_loc_y, &flags)) { - printf("\n%s: mouse has no Y report\n", self->dv_xname); - return ENXIO; - } + hid_input, &ms->sc_loc_y, &flags)) + ms->sc_loc_y.size = 0; + switch(flags & MOUSE_FLAGS_MASK) { case 0: ms->sc_flags |= HIDMS_ABSY; @@ -292,7 +290,7 @@ hidms_attach(struct hidms *ms, const struct wsmouse_accessops *ops) #endif printf(": %d button%s", - ms->sc_num_buttons, ms->sc_num_buttons <= 1 ? "" : "s"); + ms->sc_num_buttons, ms->sc_num_buttons == 1 ? "" : "s"); switch (ms->sc_flags & (HIDMS_Z | HIDMS_W)) { case HIDMS_Z: printf(", Z dir");
Re: [Diff] Implement multiple device cloning for hotplug
On Tue, 11 May 2021 at 22:37:55 -0400, Ashton Fagg wrote: > Inspiration for this diff was drawn from Joshua Stein [1], seeminly he > had a use-case that was somewhat similar to mine at one point but it > doesn't look like this was ever committed. Nor can I find any discussion > on it. I'm glad I could inspire you to repost the work I already did years ago. On Tue, 11 May 2021 at 20:53:17 -0600, Theo de Raadt wrote: > Unfortunately there is no instrumentation in drivers or subsystems to > capture "ready to do work", and create the events at that point instead. > hotplug is hooked into subr_autoconf.c, this code is for handling the > device heirarchy, but it is not involved in operation, and thus unaware > of "readiness". Fixing this would require a subsystem by subsystem study, > figuring out where the glue should exist, and creating the events at > the CORRECT time. When this same objection was raised in 2018 when I proposed this, I said that I looked through the bugs archives and could only find references to hotplug-related issues 8 years prior, and they were considered solved: https://marc.info/?l=openbsd-bugs&m=127990199813627&w=2 I also proposed this diff, which individual drivers could use to defer hotplug notification from their attach routine if they needed to do extra work before becoming "ready". No one spoke up of any drivers needing such functionality, and all of this work was ignored since you and Mark wanted the Xorg input device notifications to come through wscons instead of hotplug. But either way, if a driver is causing a panic because it responds before it is ready, the same thing would happen without hotplug if it was communicated with at the wrong time (like some script running in a loop). Those drivers should just not respond to ioctls or whatever they are doing before they are ready rather than just hoping that no one sees their attachment too early. diff --git sys/dev/hotplug.c sys/dev/hotplug.c index e1e7bad95c9..434c43f4135 100644 --- sys/dev/hotplug.c +++ sys/dev/hotplug.c @@ -73,6 +73,12 @@ hotplug_device_attach(enum devclass class, char *name) hotplug_put_event(&he); } +void +hotplug_defer_attach(struct device *dev) +{ + dev->dv_flags |= DVF_HOTPLUG_DEFER; +} + void hotplug_device_detach(enum devclass class, char *name) { diff --git sys/kern/subr_autoconf.c sys/kern/subr_autoconf.c index 13fafc6994e..e09f11486c0 100644 --- sys/kern/subr_autoconf.c +++ sys/kern/subr_autoconf.c @@ -403,7 +403,7 @@ config_attach(struct device *parent, void *match, void *aux, cfprint_t print) (*ca->ca_attach)(parent, dev, aux); config_process_deferred_children(dev); #if NHOTPLUG > 0 - if (!cold) + if (!cold && !(dev->dv_flags & DVF_HOTPLUG_DEFER)) hotplug_device_attach(cd->cd_class, dev->dv_xname); #endif diff --git sys/sys/device.h sys/sys/device.h index 90827f53503..b73b248d040 100644 --- sys/sys/device.h +++ sys/sys/device.h @@ -81,7 +81,8 @@ struct device { }; /* dv_flags */ -#defineDVF_ACTIVE 0x0001 /* device is activated */ +#defineDVF_ACTIVE 0x0001 /* device is activated */ +#defineDVF_HOTPLUG_DEFER 0x0002 /* defer hotplug announce */ TAILQ_HEAD(devicelist, device); diff --git sys/sys/hotplug.h sys/sys/hotplug.h index f2da3f6cfd8..7e68482a428 100644 --- sys/sys/hotplug.h +++ sys/sys/hotplug.h @@ -35,6 +35,7 @@ struct hotplug_event { #ifdef _KERNEL void hotplug_device_attach(enum devclass, char *); void hotplug_device_detach(enum devclass, char *); +void hotplug_defer_attach(struct device *); #endif #endif /* _SYS_HOTPLUG_H_ */
Re: virtio(4) at fdt: version 2 for Parallels 16 on Mac (M1)
On Wed, 14 Apr 2021 at 22:55:14 +0200, Mark Kettenis wrote: > > cpu0 at mainbus0 mpidr 0: Unknown, MIDR 0x410f > > That's a strange ARM CPU ;). > > If you have some time, can you run a make -j in /usr/src/lib/libc? > I'm curious if cc or ld crashes in a virtual machine. I just built all of libc with -j2 within Parallels on my M1 MBA without any crashes.
xf86-input-ws: fix hotplugging usb mice on legacy-free machines
The X server's autoconfiguration probes each /dev/wsmouseN device and if its WSMOUSEIO_GTYPE ioctl returns something like WSMOUSE_TYPE_TOUCHPAD, xf86-input-ws attaches to that device directly which causes the wsmouse device to detach from the mux. This allows xinput to handle these special devices separately each with their own configuration. The last part of the X server configuration loop is this: /* Add a default entry catching all other mux elements as "ws" */ wscons_add_pointer(WSCONS_MOUSE_PREFIX, "ws", ATTR_POINTER); For any simple mice like a basic USB one, they will remain in the mux and the wsmux ioctl handler will route WSMOUSEIO_GTYPE to the first wsmouse device in the mux. xf86-input-ws will attach to /dev/wsmouse and all USB mouse traffic will flow through that single device properly, even if the mouse is unplugged and plugged back in later. However, if X is started when there are no other mice attached to the mux (because nothing is attached or because it already took the non-simple devices out of the mux), WSMOUSEIO_GTYPE will fail and xf86-input-ws will bail due to the bad ioctl response: [ 2459.571] (II) config/wscons: checking input device /dev/wsmouse [ 2459.571] (II) Using input driver 'ws' for '/dev/wsmouse' [ 2459.571] (**) /dev/wsmouse: always reports core events [ 2459.571] (II) ws: /dev/wsmouse: debuglevel 0 [ 2459.571] (**) Option "Device" "/dev/wsmouse" [ 2459.571] (**) ws: /dev/wsmouse: ZAxisMapping: buttons 4 and 5 [ 2459.571] (**) ws: /dev/wsmouse: WAxisMapping: buttons 6 and 7 [ 2459.571] (**) ws: /dev/wsmouse: associated screen: 0 [ 2459.571] (EE) PreInit returned 2 for "/dev/wsmouse" [ 2459.571] (II) UnloadModule: "ws" Later, if a USB mouse is attached while X is running, it sends its data through the wsmouse mux but the X server isn't listening to it. To remedy this, make xf86-input-ws ignore a bad WSMOUSEIO_GTYPE ioctl response if it's talking to the mux device, and just assume it will be USB mouse traffic. This hasn't affected "legacy" laptops because they often have a pms(4) port which remains the default device in the wsmouse mux even if there isn't an actual mouse attached to that port. (This doesn't solve the issue of a device like a umt(4) attached after starting X not being treated as its own device because X would need to open that device directly. That can't easily be solved right now.) diff --git driver/xf86-input-ws/src/ws.c driver/xf86-input-ws/src/ws.c index 894704877..ebbf24615 100644 --- driver/xf86-input-ws/src/ws.c +++ driver/xf86-input-ws/src/ws.c @@ -67,6 +67,8 @@ static Atom prop_swap; int ws_debug_level = 0; #endif +#define WSMOUSE_MUX_DEVICE "/dev/wsmouse" + static XF86ModuleVersionInfo VersionRec = { "ws", MODULEVENDORSTRING, @@ -212,8 +214,17 @@ wsPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) } if (wsOpen(pInfo) != Success) goto fail; - if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0) - goto fail; + if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, &priv->type) != 0) { + if (strcmp(priv->devName, WSMOUSE_MUX_DEVICE) == 0) + /* +* No mice are currently connected to the mux, assume +* any traffic we see on it later will come from a USB +* mouse. +*/ + priv->type = WSMOUSE_TYPE_USB; + else + goto fail; + } if (priv->type == WSMOUSE_TYPE_TPANEL) { pInfo->type_name = XI_TOUCHSCREEN; priv->raw = xf86SetBoolOption(pInfo->options, "Raw", 1);
uhidev: allow devices to match specific multiple reports
uhidev allows a child device to claim all reports by calling *_match functions with the report id set to UHIDEV_CLAIM_ALLREPORTID. umt needs this because it has to access 3 reports which has worked okay up until now because devices with umt and a ukbd have usually presented them on separate uhidev devices. However, on a new Surface Type Cover device, someone reported that these devices are on the same uhidev meaning if umt attaches, the ukbd device can't. To remedy this, probe devices with UHIDEV_CLAIM_MULTIPLE_REPORTID instead and include an array in the uhidev_attach_arg the size of the available reports. Devices wanting to claim multiple reports just set the indexes in the array to 1 that it wants to claim and uhidev will reserve those, but still probe other devices with each specific unclaimed id. umt is modified to do its report finding in its match function so it can claim just the specific reports it needs. Index: dev/usb/uhidev.c === RCS file: /cvs/src/sys/dev/usb/uhidev.c,v retrieving revision 1.89 diff -u -p -u -p -r1.89 uhidev.c --- dev/usb/uhidev.c15 Feb 2021 11:26:00 - 1.89 +++ dev/usb/uhidev.c5 Mar 2021 14:51:09 - @@ -250,21 +250,27 @@ uhidev_attach(struct device *parent, str uha.uaa = uaa; uha.parent = sc; - uha.reportid = UHIDEV_CLAIM_ALLREPORTID; + uha.reportid = UHIDEV_CLAIM_MULTIPLE_REPORTID; + uha.nreports = nrepid; + uha.claimed = malloc(nrepid, M_TEMP, M_WAITOK|M_ZERO); - /* Look for a driver claiming all report IDs first. */ + /* Look for a driver claiming multiple report IDs first. */ dev = config_found_sm(self, &uha, NULL, uhidevsubmatch); if (dev != NULL) { for (repid = 0; repid < nrepid; repid++) { /* * Could already be assigned by uhidev_set_report_dev(). */ - if (sc->sc_subdevs[repid] == NULL) + if (sc->sc_subdevs[repid] != NULL) + continue; + + if (uha.claimed[repid]) sc->sc_subdevs[repid] = (struct uhidev *)dev; } - return; } + free(uha.claimed, M_TEMP, nrepid); + for (repid = 0; repid < nrepid; repid++) { DPRINTF(("%s: try repid=%d\n", __func__, repid)); if (hid_report_size(desc, size, hid_input, repid) == 0 && @@ -355,7 +361,7 @@ uhidevprint(void *aux, const char *pnp) if (pnp) printf("uhid at %s", pnp); - if (uha->reportid != 0 && uha->reportid != UHIDEV_CLAIM_ALLREPORTID) + if (uha->reportid != 0 && uha->reportid != UHIDEV_CLAIM_MULTIPLE_REPORTID) printf(" reportid %d", uha->reportid); return (UNCONF); } Index: dev/usb/umt.c === RCS file: /cvs/src/sys/dev/usb/umt.c,v retrieving revision 1.2 diff -u -p -u -p -r1.2 umt.c --- dev/usb/umt.c 23 Aug 2020 11:08:02 - 1.2 +++ dev/usb/umt.c 5 Mar 2021 14:51:09 - @@ -61,8 +61,8 @@ const struct wsmouse_accessops umt_acces }; intumt_match(struct device *, void *, void *); -intumt_find_winptp_reports(struct uhidev_softc *, void *, int, - struct umt_softc *); +intumt_find_winptp_reports(struct uhidev_softc *, void *, int, int *, + int *, int *); void umt_attach(struct device *, struct device *, void *); intumt_hidev_get_report(struct device *, int, int, void *, int); intumt_hidev_set_report(struct device *, int, int, void *, int); @@ -83,13 +83,19 @@ int umt_match(struct device *parent, void *match, void *aux) { struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; + int input = 0, conf = 0, cap = 0; int size; void *desc; - if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID) { + if (uha->reportid == UHIDEV_CLAIM_MULTIPLE_REPORTID) { uhidev_get_report_desc(uha->parent, &desc, &size); - if (umt_find_winptp_reports(uha->parent, desc, size, NULL)) + if (umt_find_winptp_reports(uha->parent, desc, size, &input, + &conf, &cap)) { + uha->claimed[input] = 1; + uha->claimed[conf] = 1; + uha->claimed[cap] = 1; return (UMATCH_DEVCLASS_DEVSUBCLASS); + } } return (UMATCH_NONE); @@ -97,16 +103,17 @@ umt_match(struct device *parent, void *m int umt_find_winptp_reports(struct uhidev_softc *parent, void *desc, int size, -struct umt_softc *sc) +int *input, int *config, int *cap) { int repid; - int input = 0, conf = 0, cap = 0; + int finput = 0, fconf = 0, fcap = 0; - if (sc != NULL) { - sc->sc_rep_inpu
ddb: resize when new console attaches
This way we aren't wrapping ddb output lines halfway across the screen on a modern console. diff --git sys/ddb/db_output.c sys/ddb/db_output.c index 77fd0e34944..72b9a24e761 100644 --- sys/ddb/db_output.c +++ sys/ddb/db_output.c @@ -252,3 +252,10 @@ stacktrace_print(struct stacktrace *st, int (*pr)(const char *, ...)) if (st->st_count == 0) (*pr)("\n"); } + +void +db_resize(int cols, int rows) +{ + db_max_width = cols; + db_max_line = rows; +} diff --git sys/ddb/db_output.h sys/ddb/db_output.h index 86ca761acaa..855bcc39a12 100644 --- sys/ddb/db_output.h +++ sys/ddb/db_output.h @@ -41,6 +41,7 @@ int db_printf(const char *, ...) int db_vprintf(const char *, va_list) __attribute__((__format__(__kprintf__,1,0))); void db_end_line(int); +void db_resize(int, int); /* * This is a replacement for the non-standard %z, %n and %r printf formats diff --git sys/dev/wscons/wsdisplay.c sys/dev/wscons/wsdisplay.c index 82daa85dda3..428019621c6 100644 --- sys/dev/wscons/wsdisplay.c +++ sys/dev/wscons/wsdisplay.c @@ -65,6 +65,10 @@ #include #endif +#ifdef DDB +#include +#endif + #include "wsmoused.h" struct wsscreen_internal { @@ -836,6 +840,10 @@ wsdisplay_cnattach(const struct wsscreen_descr *type, void *cookie, int ccol, cn_tab = &wsdisplay_cons; wsdisplay_console_initted = 1; + +#ifdef DDB + db_resize(type->ncols, type->nrows); +#endif } /*
ims: claim to be a touchpad
There are no i2c-connected mice and ims(4) will always be a touchpad/touchscreen/stylus that just doesn't meet the requirements of imt(4). Presenting it as WSMOUSE_TYPE_TOUCHPAD makes the X server set it up as a separate pointer which may be useful. Index: sys/dev/i2c/ims.c === RCS file: /cvs/src/sys/dev/i2c/ims.c,v retrieving revision 1.2 diff -u -p -u -p -r1.2 ims.c --- sys/dev/i2c/ims.c 1 Sep 2018 20:50:16 - 1.2 +++ sys/dev/i2c/ims.c 21 Jan 2021 03:39:00 - @@ -180,8 +180,7 @@ ims_ioctl(void *v, u_long cmd, caddr_t d switch (cmd) { case WSMOUSEIO_GTYPE: - /* XXX: should we set something else? */ - *(u_int *)data = WSMOUSE_TYPE_USB; + *(u_int *)data = WSMOUSE_TYPE_TOUCHPAD; return 0; default: return -1; Index: share/man/man4/ims.4 === RCS file: /cvs/src/share/man/man4/ims.4,v retrieving revision 1.3 diff -u -p -u -p -r1.3 ims.4 --- share/man/man4/ims.430 Jul 2016 15:44:45 - 1.3 +++ share/man/man4/ims.421 Jan 2021 03:39:00 - @@ -19,14 +19,14 @@ .Os .Sh NAME .Nm ims -.Nd I2C HID mouse support +.Nd I2C HID pointing device support .Sh SYNOPSIS .Cd "ims* at ihidev?" .Cd "wsmouse* at ims? mux 0" .Sh DESCRIPTION The .Nm -driver provides support for I2C HID mice. +driver provides support for I2C HID touchpads and other pointing devices. Access to these devices is through the .Xr wscons 4 driver.
Re: tpm(4): removing tvtohz(9)?
On Fri, 18 Dec 2020 at 18:58:43 -0600, Scott Cheloha wrote: > Hi, > > tpm(4) is the last driver in the tree using tvtohz(9). There are no > remaining callers using tstohz(9), so if and when we remove tvtohz(9) > from tpm(4) we can remove both interfaces from the tree. > > tpm(4) is tricky because it converts timeouts from milliseconds to > ticks and then doesn't use tsleep(9) at all. It uses delay(9), which > takes a count of microseconds as argument. This complicates the > conversion to tsleep_nsec(9) because the units don't match up for any > of these delays. Also, delay(9) is incompatible with tsleep(9) > because tsleep(9) yields the CPU while delay(9) busy-waits. > > I don't know if we *need* to delay(9) here. What would happen if we > yielded the CPU with e.g. tsleep(9)? > > The attached patch changes the delays to use the correct units. This > is not the right thing, these timeouts are probably too large to spin > for in delay(9). I'm just guessing here. > > Aside: TPM_READ_TMO is *huge*. 2 minutes for a read timeout seems a > bit large. NetBSD's TPM_READ_TMO has been dropped to 2 seconds, like > the other timeouts. Yes, this driver sucks. Its only purpose is to make certain devices suspend and resume properly and doesn't provide any actual TPM functionality. We (someone other than me) should just take NetBSD's rewrite which also adds TPM 2 support and apparently works on MSFT0101 devices which was committed and backed out in ours because it didn't work.
Re: acpiapplesmc(4)
On Mon, 07 Sep 2020 at 06:58:01 +0200, Marcus Glocker wrote: > This is an initial driver for the Apple System Management Controller > found in Intel based Apple computers. > > The driver is currently missing support for the Sudden Motion Sensor > (SMS), light sensor, and keyboard backlight since I don't have that > hardware available to develop on. > > On my iMac11,2 it can deliver fan and temperatures values: > > hw.sensors.acpiapplesmc0.temp0=24.00 degC (Airflow 1) > hw.sensors.acpiapplesmc0.temp1=33.00 degC (CPU Core 0) > hw.sensors.acpiapplesmc0.temp2=36.00 degC (CPU Heatsink) > hw.sensors.acpiapplesmc0.temp3=40.00 degC (CPU Core 1) > hw.sensors.acpiapplesmc0.temp4=47.00 degC (GPU) > hw.sensors.acpiapplesmc0.temp5=45.00 degC (GPU Heatsink) > hw.sensors.acpiapplesmc0.temp6=59.00 degC (PCH) > hw.sensors.acpiapplesmc0.temp7=42.00 degC (Memory) > hw.sensors.acpiapplesmc0.temp8=45.00 degC (Mainboard Proximity) > hw.sensors.acpiapplesmc0.fan0=998 RPM > hw.sensors.acpiapplesmc0.fan1=1132 RPM > hw.sensors.acpiapplesmc0.fan2=1198 RPM > > Feedback, testers, OKs? Are there machines where asmc(4) will also attach?
exar XR17V35x (again)
In 2018 I added support for Exar XR17V35x serial ports: The Exar XR17V354 has 4 com ports that have a 256-byte FIFO, use a frequency of 125Mhz, and have a unique sleep register. A custom interrupt handler is setup in puc for these ports so it can check a register which reports which ports triggered the interrupt, rather than having to run comintr for every port every time. https://github.com/openbsd/src/commit/21514470a28cb3682074159e69358d924e73f5f1 This was backed out shortly after: Revert previous commit; the XR17V35X probe that was added accesses registers that aren't guaranteed to be there and may even belong to a different device. This triggers a fault on hppa machines like the C3000 for example. https://github.com/openbsd/src/commit/9f2c39383ee470c5b76fb828f64ea58341b214e9 https://github.com/openbsd/src/commit/b40f90ead5d17e757784d1aa91d0d0406ce61d20 I needed this again, so this version sets the sc_uarttype in com_puc_attach ahead of time because the type of port is already known (from pucdata.c). This avoids any probe in com_attach_subr which previously tried to upgrade from COM_UART_16550A to COM_UART_XR17V35X. puc0 at pci4 dev 0 function 0 "Exar XR17V354" rev 0x03: ports: 16 com com4 at puc0 port 0 apic 5 int 16: xr17v35x, 256 byte fifo com5 at puc0 port 1 apic 5 int 16: xr17v35x, 256 byte fifo com6 at puc0 port 2 apic 5 int 16: xr17v35x, 256 byte fifo com7 at puc0 port 3 apic 5 int 16: xr17v35x, 256 byte fifo Index: sys/dev/ic/com.c === RCS file: /cvs/src/sys/dev/ic/com.c,v retrieving revision 1.172 diff -u -p -u -p -r1.172 com.c --- sys/dev/ic/com.c9 Mar 2020 04:38:46 - 1.172 +++ sys/dev/ic/com.c5 Aug 2020 21:35:02 - @@ -306,6 +306,9 @@ comopen(dev_t dev, int flag, int mode, s case COM_UART_TI16750: com_write_reg(sc, com_ier, 0); break; + case COM_UART_XR17V35X: + com_write_reg(sc, UART_EXAR_SLEEP, 0); + break; } } @@ -498,6 +501,9 @@ compwroff(struct com_softc *sc) case COM_UART_TI16750: com_write_reg(sc, com_ier, IER_SLEEP); break; + case COM_UART_XR17V35X: + com_write_reg(sc, UART_EXAR_SLEEP, 0xff); + break; } } } @@ -533,6 +539,9 @@ com_resume(struct com_softc *sc) case COM_UART_TI16750: com_write_reg(sc, com_ier, 0); break; + case COM_UART_XR17V35X: + com_write_reg(sc, UART_EXAR_SLEEP, 0); + break; } } @@ -919,7 +928,7 @@ comstart(struct tty *tp) } if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) { - u_char buffer[128]; /* largest fifo */ + u_char buffer[256]; /* largest fifo */ int i, n; n = q_to_b(&tp->t_outq, buffer, @@ -1466,6 +1475,11 @@ com_attach_subr(struct com_softc *sc) break; #endif #endif + case COM_UART_XR17V35X: + printf(": xr17v35x, 256 byte fifo\n"); + SET(sc->sc_hwflags, COM_HW_FIFO); + sc->sc_fifolen = 256; + break; default: panic("comattach: bad fifo type"); } @@ -1473,7 +1487,8 @@ com_attach_subr(struct com_softc *sc) #ifdef COM_CONSOLE if (!ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) #endif - com_fifo_probe(sc); + if (sc->sc_fifolen < 256) + com_fifo_probe(sc); if (sc->sc_fifolen == 0) { CLR(sc->sc_hwflags, COM_HW_FIFO); Index: sys/dev/ic/comreg.h === RCS file: /cvs/src/sys/dev/ic/comreg.h,v retrieving revision 1.19 diff -u -p -u -p -r1.19 comreg.h --- sys/dev/ic/comreg.h 2 May 2018 13:20:12 - 1.19 +++ sys/dev/ic/comreg.h 5 Aug 2020 21:35:02 - @@ -182,6 +182,11 @@ #defineCOM_NPORTS 8 +/* Exar XR17V35X */ +#define UART_EXAR_INT0 0x80 +#define UART_EXAR_SLEEP0x8b/* Sleep mode */ +#define UART_EXAR_DVID 0x8d/* Device identification */ + /* * WARNING: Serial console is assumed to be at COM1 address */ Index: sys/dev/ic/comvar.h === RCS file: /cvs/src/sys/dev/ic/comvar.h,v retrieving revision 1.57 diff -u -p -u -p -r1.57 comvar.h --- sys/dev/ic/comvar.h 14 May 2018 19:25:54 - 1.57 +++ sys/dev/ic/comvar.h 5 Aug 2020 21:35:02 - @@ -103,6 +103,7 @@ struct com_softc { #defineCOM_UART_ST16C654 0x08/* 64 bytes fifo */ #defineCOM_UART_XR168500x10
imt/hidmt: work better with dual touchpad/trackstick devices
struct ihidev_attach_arg { struct i2c_attach_args *iaa; struct ihidev_softc *parent; uint8_t reportid; -#defineIHIDEV_CLAIM_ALLREPORTID255 + uint8_t claims[16]; + uint8_t nclaims; +#defineIHIDEV_CLAIM_MULTIPLEID 255 }; struct i2c_hid_report_request { diff --git sys/dev/i2c/imt.c sys/dev/i2c/imt.c index 38169837338..5a699921498 100644 --- sys/dev/i2c/imt.c +++ sys/dev/i2c/imt.c @@ -3,7 +3,7 @@ * HID-over-i2c multitouch trackpad driver for devices conforming to * Windows Precision Touchpad standard * - * https://msdn.microsoft.com/en-us/library/windows/hardware/dn467314%28v=vs.85%29.aspx + * https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections * * Copyright (c) 2016 joshua stein * @@ -79,13 +79,19 @@ int imt_match(struct device *parent, void *match, void *aux) { struct ihidev_attach_arg *iha = (struct ihidev_attach_arg *)aux; + struct imt_softc sc; int size; void *desc; - if (iha->reportid == IHIDEV_CLAIM_ALLREPORTID) { + if (iha->reportid == IHIDEV_CLAIM_MULTIPLEID) { ihidev_get_report_desc(iha->parent, &desc, &size); - if (imt_find_winptp_reports(iha->parent, desc, size, NULL)) + if (imt_find_winptp_reports(iha->parent, desc, size, &sc)) { + iha->claims[0] = sc.sc_rep_input; + iha->claims[1] = sc.sc_rep_config; + iha->claims[2] = sc.sc_rep_cap; + iha->nclaims = 3; return (IMATCH_DEVCLASS_DEVSUBCLASS); + } } return (IMATCH_NONE);
Re: Give support to the 2019 Apple's MBP (13-inch)
On Thu, 11 Jun 2020 at 08:29:12 +0200, Romero Pérez, Abel wrote: > Hello, > > I tried to install stable flavor from USB on the MBP 13-inch 2019, with no > luck, and the following issues: > > 1. Booting kernel messages > > Centered on the screen, with a very small size, not working well for > reading. That is due to there being limited space in the ramdisks for an additional font. Once you boot to a normal kernel after installation you'll get a larger font. > 2. After booting, keyboard not working > > I had to connect an USB KB. The T2-chip MacBooks connect the keyboard and touchpad behind the T2 chip, requiring a custom driver to interface with it and "unlock" the virtual USB host controller. A Linux driver that does this is at https://github.com/MCMrARM/mbp2018-bridge-drv > 3. Couldn't install on disk > > I can't ensure I installed the OS on the SSD because I got some errors when > choosing the to install device. But the font was very small... Apple has used some weird NVMe devices in their recent laptops. I'm not sure specifically what is required for the 2019 MBP though. It's going to be a lot of work to get OpenBSD (or Linux for that matter) running on that machine, and who knows what other components will not work properly after installation. It's probably not worth the hassle. The pre-T2 2015 MacBook Pro works ok.
Re: acpihid: INT33D5 driver
Here is a new revision that tries to call methods through the node's _DSM first, as it does on Linux. It also no longer takes over power button handling as requested by Mark. acpihid.3 diff --git share/man/man4/Makefile share/man/man4/Makefile index 2cce0a9a132..bb0b6b10068 100644 --- share/man/man4/Makefile +++ share/man/man4/Makefile @@ -3,6 +3,7 @@ MAN= aac.4 abcrtc.4 ac97.4 acphy.4 acrtc.4 \ acpi.4 acpiac.4 acpials.4 acpiasus.4 acpibat.4 \ acpibtn.4 acpicbkbd.4 acpicpu.4 acpidock.4 acpihve.4 acpiec.4 \ + acpihid.4 \ acpihpet.4 acpimadt.4 acpimcfg.4 acpipci.4 acpiprt.4 acpipwrres.4 \ acpisbs.4 acpisony.4 acpisurface.4 acpithinkpad.4 acpitoshiba.4 \ acpitimer.4 acpivideo.4 acpivout.4 acpitz.4 \ diff --git share/man/man4/acpi.4 share/man/man4/acpi.4 index 232d1cd6921..1fba9f5a22d 100644 --- share/man/man4/acpi.4 +++ share/man/man4/acpi.4 @@ -56,6 +56,8 @@ ACPI processor power and performance state ACPI docking station .It Xr acpiec 4 ACPI embedded controller +.It Xr acpihid 4 +ACPI HID event and 5-button array .It Xr acpihpet 4 ACPI high precision event timer .It Xr acpihve 4 diff --git share/man/man4/acpihid.4 share/man/man4/acpihid.4 new file mode 100644 index 000..d9914cec7b7 --- /dev/null +++ share/man/man4/acpihid.4 @@ -0,0 +1,42 @@ +.\"$OpenBSD$ +.\" +.\" Copyright (c) 2020 joshua stein +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate$ +.Dt ACPIHID 4 +.Os +.Sh NAME +.Nm acpihid +.Nd ACPI HID event and 5-button array +.Sh SYNOPSIS +.Cd "acpihid* at acpi?" +.Sh DESCRIPTION +The +.Nm +driver supports ACPI HID events and 5-button array devices found on some +tablet devices. +.Sh SEE ALSO +.Xr acpi 4 , +.Sh HISTORY +The +.Nm +driver first appeared in +.Ox 6.8 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An joshua stein Aq Mt j...@jcs.org . diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC index 9aa0a390690..618f49fadda 100644 --- sys/arch/amd64/conf/GENERIC +++ sys/arch/amd64/conf/GENERIC @@ -71,6 +71,7 @@ acpials* at acpi? tpm* at acpi? acpihve* at acpi? acpisurface* at acpi? +acpihid* at acpi? ipmi0 at acpi? disable ccpmic*at iic? tipmic*at iic? diff --git sys/dev/acpi/acpihid.c sys/dev/acpi/acpihid.c new file mode 100644 index 000..063fee1dc21 --- /dev/null +++ sys/dev/acpi/acpihid.c @@ -0,0 +1,401 @@ +/* $OpenBSD$ */ +/* + * ACPI HID event and 5-button array driver + * + * Copyright (c) 2018, 2020 joshua stein + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "audio.h" +#include "wskbd.h" + +/* #define ACPIHID_DEBUG */ +#define ACPIHID_DEBUG + +#ifdef ACPIHID_DEBUG +#define DPRINTF(x) printf x +#else +#define DPRINTF(x) +#endif + +struct acpihid_softc { + struct device sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + struct acpi_softc *sc_acpi; + struct aml_node *sc_devnode; + int sc_5_button; + + /* +* HEBC v1 +* 0 - Rotation Lock, Num Lock, Home, End, Page Up, Page Down +* 1 - Wireless Radio Control +* 2 - System Power Down +* 3 - System Hibernate +* 4 - System Sleep/ S
umstc: Microsoft Surface Type Cover driver
This makes the volume and screen brightness keys work, but more importantly it keeps the USB data/interrupt pipes open at all times because otherwise the Type Cover resets itself (or at least detaches and reattaches) when these buttons are pressed. diff --git share/man/man4/Makefile share/man/man4/Makefile index 258399f2e7a..3c15cc14285 100644 --- share/man/man4/Makefile +++ share/man/man4/Makefile @@ -84,8 +84,8 @@ MAN= aac.4 abcrtc.4 ac97.4 acphy.4 acrtc.4 \ uftdi.4 ugen.4 ugl.4 ugold.4 uguru.4 uhci.4 uhid.4 uhidev.4 uipaq.4 \ uk.4 ukbd.4 \ ukphy.4 ulpt.4 umass.4 umb.4 umbg.4 umcs.4 umct.4 umidi.4 umodem.4 \ - ums.4 umsm.4 umt.4 unix.4 uonerng.4 uow.4 uoaklux.4 uoakrh.4 uoakv.4 \ - upd.4 upgt.4 upl.4 uplcom.4 ural.4 ure.4 url.4 urlphy.4 \ + ums.4 umsm.4 umstc.4 umt.4 unix.4 uonerng.4 uow.4 uoaklux.4 uoakrh.4 \ + uoakv.4 upd.4 upgt.4 upl.4 uplcom.4 ural.4 ure.4 url.4 urlphy.4 \ urndis.4 urng.4 urtw.4 urtwn.4 usb.4 uscom.4 uslcom.4 usps.4 \ uthum.4 uticom.4 utpms.4 utwitch.4 utrh.4 uts.4 utvfu.4 uvideo.4 \ uvisor.4 uvscom.4 uwacom.4 uxrcom.4 \ diff --git share/man/man4/umstc.4 share/man/man4/umstc.4 new file mode 100644 index 000..da557c59d1d --- /dev/null +++ share/man/man4/umstc.4 @@ -0,0 +1,44 @@ +.\"$OpenBSD$ +.\" +.\" Copyright (c) 2020 joshua stein +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate$ +.Dt UMSTC 4 +.Os +.Sh NAME +.Nm umstc +.Nd Microsoft Surface Type Cover driver +.Sh SYNOPSIS +.Cd "umstc* at uhidev?" +.Sh DESCRIPTION +The +.Nm +driver responds to some special keys on the Microsoft Type Cover +keyboard, such as volume and screen brightness keys. +.Sh SEE ALSO +.Xr uhidev 4 , +.Xr usb 4 , +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Ox 6.8 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An joshua stein Aq Mt j...@jcs.org . diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC index b77a3b4ead5..624f73bb7cc 100644 --- sys/arch/amd64/conf/GENERIC +++ sys/arch/amd64/conf/GENERIC @@ -284,6 +284,7 @@ ucom* at uslhcom? uhid* at uhidev? # USB generic HID support fido* at uhidev? # FIDO/U2F security key support upd* at uhidev? # USB Power Devices sensors +umstc* at uhidev? # Microsoft Surface Type Cover aue* at uhub?# ADMtek AN986 Pegasus Ethernet atu* at uhub?# Atmel AT76c50x based 802.11b axe* at uhub?# ASIX Electronics AX88172 USB Ethernet diff --git sys/dev/hid/hid.h sys/dev/hid/hid.h index 17de4065e0c..c528ab9551b 100644 --- sys/dev/hid/hid.h +++ sys/dev/hid/hid.h @@ -396,6 +396,11 @@ inthid_is_collection(const void *, int, uint8_t, int32_t); #define HUL_KANA 0x0005 /* Usages, Consumer */ +#define HUC_CONTROL0x0001 +#define HUC_PLAY_PAUSE 0x00cd +#define HUC_MUTE 0x00e2 +#define HUC_VOL_INC0x00e9 +#define HUC_VOL_DEC0x00ea #define HUC_AC_PAN 0x0238 /* Usages, FIDO */ diff --git sys/dev/usb/files.usb sys/dev/usb/files.usb index c3597c54775..fc5ff46ce76 100644 --- sys/dev/usb/files.usb +++ sys/dev/usb/files.usb @@ -473,3 +473,8 @@ filedev/usb/uwacom.cuwacom attach bwfm at uhub with bwfm_usb: firmload file dev/usb/if_bwfm_usb.c bwfm_usb + +# Microsoft Surface Type Cover +device umstc: hid +attach umstc at uhidbus +file dev/usb/umstc.c umstc diff --git sys/dev/usb/umstc.c sys/dev/usb/umstc.c new file mode 100644 index 000..df995181bf6 --- /dev/null +++ sys/dev/usb/umstc.c @@ -0,0 +1,172 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2020 joshua stein + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS.
acpihid: INT33D5 driver
A driver for tablet hardware buttons which seems to be a standardized interface. Used on the Surface Go. When pressing the power button, the driver receives a button down and then a button up event, unlike acpibtn. Since there may be an opportunity to do something different based on the duration of the button press, it takes over shutdown/suspend from acpibtn(4). diff --git share/man/man4/Makefile share/man/man4/Makefile index 2d9a57d3814..258399f2e7a 100644 --- share/man/man4/Makefile +++ share/man/man4/Makefile @@ -3,6 +3,7 @@ MAN= aac.4 abcrtc.4 ac97.4 acphy.4 acrtc.4 \ acpi.4 acpiac.4 acpials.4 acpiasus.4 acpibat.4 \ acpibtn.4 acpicbkbd.4 acpicpu.4 acpidock.4 acpihve.4 acpiec.4 \ + acpihid.4 \ acpihpet.4 acpimadt.4 acpimcfg.4 acpipci.4 acpiprt.4 acpipwrres.4 \ acpisbs.4 acpisony.4 acpisurface.4 acpithinkpad.4 acpitoshiba.4 \ acpitimer.4 acpivideo.4 acpivout.4 acpitz.4 \ diff --git share/man/man4/acpihid.4 share/man/man4/acpihid.4 new file mode 100644 index 000..8d54da962d1 --- /dev/null +++ share/man/man4/acpihid.4 @@ -0,0 +1,47 @@ +.\"$OpenBSD$ +.\" +.\" Copyright (c) 2020 joshua stein +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate$ +.Dt ACPIHID 4 +.Os +.Sh NAME +.Nm acpihid +.Nd ACPI HID event and 5-button array driver +.Sh SYNOPSIS +.Cd "acpihid* at acpi?" +.Sh DESCRIPTION +The +.Nm +driver supports ACPI HID events and 5-button array devices found on some +tablet devices. +Power button events are processed according to the +.Va machdep.pwraction +sysctl value. +.Sh SEE ALSO +.Xr acpi 4 , +.Xr acpibtn 4 , +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Ox 6.8 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An joshua stein Aq Mt j...@jcs.org . diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC index 87893bfafea..b77a3b4ead5 100644 --- sys/arch/amd64/conf/GENERIC +++ sys/arch/amd64/conf/GENERIC @@ -71,6 +71,7 @@ acpials* at acpi? tpm* at acpi? acpihve* at acpi? acpisurface* at acpi? +acpihid* at acpi? ipmi0 at acpi? disable ccpmic*at iic? tipmic*at iic? diff --git sys/dev/acpi/acpi.c sys/dev/acpi/acpi.c index 7c103347980..306419761c7 100644 --- sys/dev/acpi/acpi.c +++ sys/dev/acpi/acpi.c @@ -72,6 +72,7 @@ int acpi_debug = 16; intacpi_poll_enabled; intacpi_hasprocfvs; intacpi_haspci; +intacpi_hashidpower; #define ACPIEN_RETRIES 15 @@ -2025,6 +2026,9 @@ acpi_pbtn_task(void *arg0, int dummy) en | ACPI_PM1_PWRBTN_EN); splx(s); + if (acpi_hashidpower) + return; + switch (pwr_action) { case 0: break; diff --git sys/dev/acpi/acpibtn.c sys/dev/acpi/acpibtn.c index da3b59ef084..e0b759121ee 100644 --- sys/dev/acpi/acpibtn.c +++ sys/dev/acpi/acpibtn.c @@ -270,6 +270,9 @@ sleep: #endif /* SMALL_KERNEL */ break; case ACPIBTN_POWER: + if (acpi_hashidpower) + break; + if (notify_type == 0x80) { switch (pwr_action) { case 0: diff --git sys/dev/acpi/acpihid.c sys/dev/acpi/acpihid.c new file mode 100644 index 000..5ec875a86e8 --- /dev/null +++ sys/dev/acpi/acpihid.c @@ -0,0 +1,254 @@ +/* $OpenBSD$ */ +/* + * ACPI HID event and 5-button array driver + * + * Copyright (c) 2018 joshua stein + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECT
Re: Mouse movement speed
On Sun, 17 May 2020 at 16:17:46 -0700, jo...@armadilloaerospace.com wrote: > I enabled wsmoused for console mouse support, but the cursor was > unusably fast. This is a high resolution, high update rate USB gaming > mouse, but it was off by well over an order of magnitude. > > I searched for a global mouse speed setting, but the only thing I > found was a "mouse.scale=0,0,0,0,0,0,0" in wsconsctl, and I couldn't > figure out how to use it even after reading all the source. That was added for touchscreens, to be manipulated with xtsscale(1). > No kernel code uses the samples[] array, and the samplelen field is > interpreted as raw mode when non-0, and scaled by the other values > when it is 0. Yes I think samples can go away, it's been there since importing from NetBSD and isn't used. > This explains wsconsctl's mouse.rawmode and mouse.scale[7] values, > but I still couldn't set them, getting > WSMOUSEIO_SCALIBCOORDS: Invalid argument for everything I tried. It's up to the driver (uts(4) for touchscreens, ums(4) for mice) to do something with that ioctl, and ums doesn't support it. > The user visible behavior I want to see is: > > wsconsctl mouse.speed=0.6 > > This could overload the existing DX_SCALE value, but that may still > need to be used independently for touchpad configuration, so I > think it would be better to define a new WSMOUSECFG_SPEED > parameter with the same *.12 fixed point format as > WSMOUSECFG_DX_SCALE. > > If this sounds reasonable, I will go ahead and make a diff for the > kernel and wsconsctl to implement it that with proper residuals. In X11 one can adjust mouse speed with xset(1), maybe it's easier to work with the raw values in wsmoused and add a scaling knob there? I see there's already code in wsmoused's normalize_event() to adjust speed. > For additional cleanup to make it net-negative-LoC, could everything > relating to struct wsmouse_calibcoords go away completely? It looks > like all the fields are now replicated as wsmousecfg parms and > handled at the wsmouse level for the touchpad case, so doing it at > the usb device or other level is redundant, as well as being broken > for relative moves. > > It would be nice to use parms for everything, also getting rid of > WSMOUSEIO_GTYPE and WSMOUSEIO_SRES. WSMOUSEIO_GTYPE is used by a few X11 input drivers that talk to wscons. I think WSMOUSEIO_SRES can be removed.
Re: posix_openpt: allow O_CLOEXEC
On Thu, 06 Feb 2020 at 12:41:47 -0700, Theo de Raadt wrote: > > Index: stdlib/posix_pty.c > > === > > RCS file: /cvs/src/lib/libc/stdlib/posix_pty.c,v > > retrieving revision 1.3 > > diff -u -p -u -p -r1.3 posix_pty.c > > --- stdlib/posix_pty.c 25 Jan 2019 00:19:25 - 1.3 > > +++ stdlib/posix_pty.c 6 Feb 2020 17:34:15 - > > @@ -36,7 +36,7 @@ posix_openpt(int oflag) > > > > /* User must specify O_RDWR in oflag. */ > > if ((oflag & O_ACCMODE) != O_RDWR || > > - (oflag & ~(O_ACCMODE | O_NOCTTY)) != 0) { > > + (oflag & ~(O_ACCMODE | O_NOCTTY | O_CLOEXEC)) != 0) { > > errno = EINVAL; > > return -1; > > } > > @@ -46,7 +46,11 @@ posix_openpt(int oflag) > > if (fd != -1) { > > if (ioctl(fd, PTMGET, &ptm) != -1) { > > close(ptm.sfd); > > - mfd = ptm.cfd; > > + if ((oflag & O_CLOEXEC) && > > + fcntl(ptm.cfd, F_SETFD, FD_CLOEXEC) == -1) > > + close(ptm.cfd); > > + else > > + mfd = ptm.cfd; > > } > > close(fd); > > Only on the child? The master does not get it? cfd is the master (controlling), sfd is the child/slave and is closed already.
Re: posix_openpt: allow O_CLOEXEC
On Thu, 06 Feb 2020 at 11:21:11 -0700, Todd C. Miller wrote: > On Thu, 06 Feb 2020 10:45:44 -0700, "Theo de Raadt" wrote: > > > That feels better, and will be more atomic. > > Unfortunately, we can't do this in ptmioctl() since we don't have > the index of the open ptm device to use to check for the presence > of UF_EXCLOSE. So it has to be done in libc instead. Alright, so like this then? Index: stdlib/posix_openpt.3 === RCS file: /cvs/src/lib/libc/stdlib/posix_openpt.3,v retrieving revision 1.4 diff -u -p -u -p -r1.4 posix_openpt.3 --- stdlib/posix_openpt.3 25 Jan 2019 00:19:25 - 1.4 +++ stdlib/posix_openpt.3 6 Feb 2020 17:34:15 - @@ -45,7 +45,7 @@ argument is formed by bitwise-inclusive .Tn OR Ns 'ing the following values defined in .In fcntl.h : -.Bl -tag -width O_NOCTTY -offset indent +.Bl -tag -width O_CLOEXEC -offset indent .It Dv O_RDWR Open for reading and writing. .It Dv O_NOCTTY @@ -53,6 +53,8 @@ Prevent the device from being made the c This flag has no effect on .Ox and is included for compatibility with other systems. +.It Dv O_CLOEXEC +Set the close-on-exec flag for the new file descriptor. .El .Pp The @@ -95,6 +97,10 @@ The .Fn posix_openpt function conforms to .St -p1003.1-2001 . +.Pp +The ability to use +.Dv O_CLOEXEC +is an extension to that standard. .Sh HISTORY The .Fn posix_openpt Index: stdlib/posix_pty.c === RCS file: /cvs/src/lib/libc/stdlib/posix_pty.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 posix_pty.c --- stdlib/posix_pty.c 25 Jan 2019 00:19:25 - 1.3 +++ stdlib/posix_pty.c 6 Feb 2020 17:34:15 - @@ -36,7 +36,7 @@ posix_openpt(int oflag) /* User must specify O_RDWR in oflag. */ if ((oflag & O_ACCMODE) != O_RDWR || - (oflag & ~(O_ACCMODE | O_NOCTTY)) != 0) { + (oflag & ~(O_ACCMODE | O_NOCTTY | O_CLOEXEC)) != 0) { errno = EINVAL; return -1; } @@ -46,7 +46,11 @@ posix_openpt(int oflag) if (fd != -1) { if (ioctl(fd, PTMGET, &ptm) != -1) { close(ptm.sfd); - mfd = ptm.cfd; + if ((oflag & O_CLOEXEC) && + fcntl(ptm.cfd, F_SETFD, FD_CLOEXEC) == -1) + close(ptm.cfd); + else + mfd = ptm.cfd; } close(fd); }
Re: posix_openpt: allow O_CLOEXEC
On Wed, 05 Feb 2020 at 17:48:41 -0700, Todd C. Miller wrote: > On Wed, 05 Feb 2020 15:47:37 -0600, joshua stein wrote: > > > The spec says the behavior of anything other than O_RDWR and > > O_NOCTTY is unspecified, but FreeBSD allows passing O_CLOEXEC. > > OK, but the manual needs to specify that O_CLOEXEC support is an > extension. E.g., under STANDARDS: > > The ability to use > .Dv O_CLOEXEC > is an extension to that standard. Thanks, incorporated. Index: lib/libc/stdlib/posix_openpt.3 === RCS file: /cvs/src/lib/libc/stdlib/posix_openpt.3,v retrieving revision 1.4 diff -u -p -u -p -r1.4 posix_openpt.3 --- lib/libc/stdlib/posix_openpt.3 25 Jan 2019 00:19:25 - 1.4 +++ lib/libc/stdlib/posix_openpt.3 6 Feb 2020 16:01:58 - @@ -45,7 +45,7 @@ argument is formed by bitwise-inclusive .Tn OR Ns 'ing the following values defined in .In fcntl.h : -.Bl -tag -width O_NOCTTY -offset indent +.Bl -tag -width O_CLOEXEC -offset indent .It Dv O_RDWR Open for reading and writing. .It Dv O_NOCTTY @@ -53,6 +53,8 @@ Prevent the device from being made the c This flag has no effect on .Ox and is included for compatibility with other systems. +.It Dv O_CLOEXEC +Set the close-on-exec flag for the new file descriptor. .El .Pp The @@ -95,6 +97,10 @@ The .Fn posix_openpt function conforms to .St -p1003.1-2001 . +.Pp +The ability to use +.Dv O_CLOEXEC +is an extension to that standard. .Sh HISTORY The .Fn posix_openpt Index: lib/libc/stdlib/posix_pty.c === RCS file: /cvs/src/lib/libc/stdlib/posix_pty.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 posix_pty.c --- lib/libc/stdlib/posix_pty.c 25 Jan 2019 00:19:25 - 1.3 +++ lib/libc/stdlib/posix_pty.c 6 Feb 2020 16:01:58 - @@ -36,13 +36,13 @@ posix_openpt(int oflag) /* User must specify O_RDWR in oflag. */ if ((oflag & O_ACCMODE) != O_RDWR || - (oflag & ~(O_ACCMODE | O_NOCTTY)) != 0) { + (oflag & ~(O_ACCMODE | O_NOCTTY | O_CLOEXEC)) != 0) { errno = EINVAL; return -1; } /* Get pty master and slave (this API only uses the master). */ - fd = open(PATH_PTMDEV, O_RDWR); + fd = open(PATH_PTMDEV, oflag); if (fd != -1) { if (ioctl(fd, PTMGET, &ptm) != -1) { close(ptm.sfd);
posix_openpt: allow O_CLOEXEC
The spec says the behavior of anything other than O_RDWR and O_NOCTTY is unspecified, but FreeBSD allows passing O_CLOEXEC. Index: lib/libc/stdlib/posix_openpt.3 === RCS file: /cvs/src/lib/libc/stdlib/posix_openpt.3,v retrieving revision 1.4 diff -u -p -u -p -r1.4 posix_openpt.3 --- lib/libc/stdlib/posix_openpt.3 25 Jan 2019 00:19:25 - 1.4 +++ lib/libc/stdlib/posix_openpt.3 5 Feb 2020 21:41:00 - @@ -45,7 +45,7 @@ argument is formed by bitwise-inclusive .Tn OR Ns 'ing the following values defined in .In fcntl.h : -.Bl -tag -width O_NOCTTY -offset indent +.Bl -tag -width O_CLOEXEC -offset indent .It Dv O_RDWR Open for reading and writing. .It Dv O_NOCTTY @@ -53,6 +53,8 @@ Prevent the device from being made the c This flag has no effect on .Ox and is included for compatibility with other systems. +.It Dv O_CLOEXEC +Set the close-on-exec flag for the new file descriptor. .El .Pp The Index: lib/libc/stdlib/posix_pty.c === RCS file: /cvs/src/lib/libc/stdlib/posix_pty.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 posix_pty.c --- lib/libc/stdlib/posix_pty.c 25 Jan 2019 00:19:25 - 1.3 +++ lib/libc/stdlib/posix_pty.c 5 Feb 2020 21:41:00 - @@ -36,13 +36,13 @@ posix_openpt(int oflag) /* User must specify O_RDWR in oflag. */ if ((oflag & O_ACCMODE) != O_RDWR || - (oflag & ~(O_ACCMODE | O_NOCTTY)) != 0) { + (oflag & ~(O_ACCMODE | O_NOCTTY | O_CLOEXEC)) != 0) { errno = EINVAL; return -1; } /* Get pty master and slave (this API only uses the master). */ - fd = open(PATH_PTMDEV, O_RDWR); + fd = open(PATH_PTMDEV, oflag); if (fd != -1) { if (ioctl(fd, PTMGET, &ptm) != -1) { close(ptm.sfd);
Re: iwm(4): support for MSI-X
On Wed, 20 Nov 2019 at 14:59:41 +0100, Patrick Wildt wrote: > Hi, > > on my Intel NUC 8i5BEHs that has a 9560 chip the current in-tree > support for the 9000 series does not work. The issue seems to be > the interrupt delivery. The first interrupt we wait for, which is > loading the firmware chunks, never appears. Even disabling MSI > and relying on legacy interrupts only gives me a single interrupt. > It is not clear if this is a misconfiguration on our side, or if > it is the chip's/firmware's fault. > > As it turns out, adding MSI-X support to iwm(4) fixes all my > problems on that machine so that I can use iwm(4) there reliably. > It also does not break my X395. > > NUC 8i5BEH: > iwm0 at pci0 dev 20 function 3 "Intel Dual Band Wireless AC 9560" rev 0x30, > msix > iwm0: hw rev 0x310, fw ver 34.3125811985.0, address xx:xx:xx:xx:xx:xx > > X395: > iwm0 at pci1 dev 0 function 0 "Intel Dual Band Wireless-AC 9260" rev 0x29, > msix > iwm0: hw rev 0x320, fw ver 34.3125811985.0, address xx:xx:xx:xx:xx:xx > > With MSI-X it is possible to allocate multiple vectors and assign > them to different CPUs. Linux actually tries to get at least 3 > vectors. They would like to have the command/mgmt queue, the data > queue and non-RX events on different vectors. For this you have > a table that maps events to vectors. And then there's a single > mask where you can enable/disable those events. > > For us this diff uses a single vector, a single interrupt, and we > map all events to this. Thus it tries to behave the same as if we > were simply using MSI. > > Still, we need a new interrupt handler for MSI-X, for instance > because the registers for "what event happened?" changed, and > more. I have tried modeling it so it should behave similarly > to the other interrupt handler. Unfortunately I neither know a > way to control the rfkill or trigger a software/hardware error, > so these cases are untested. > > It would be nice to get this tested, to make sure that there are > no regressions on older hardware. If we don't want to risk it, > we could also try enabling msix only for 9000 series chips, but > I'd rather see if this also works on the older variants. > > So, essentially, apply the diff and tell me if it still works as > well as it did before. :) In theory this could lead the way to > having RX processed in parallel, so there's something to gain in > the future and it's worth testing. Works on my X1 with 9560, but doesn't help the problem under heavy traffic (~40Mbit/sec download) where audio stutters and I get double key presses. iwm0 at pci0 dev 20 function 3 "Intel Dual Band Wireless AC 9560" rev 0x11, msix iwm0: hw rev 0x310, fw ver 34.3125811985.0, address 90:78:41:
Re: iwm: support 9260 devices
On Sat, 16 Nov 2019 at 19:08:05 +0100, Stefan Sperling wrote: > On Sat, Nov 16, 2019 at 11:44:03AM -0600, joshua stein wrote: > > Awesome, thanks guys. It's working great on the 9560 on my ThinkPad > > X1C7. A speed test showed 44/18 Mbps and it continues to work fine > > after an S3 cycle. > > Great :-) > > > The firmware version string looks odd: > > > > iwm0 at pci0 dev 20 function 3 "Intel Dual Band Wireless AC 9560" rev 0x11, > > msi > > iwm0: hw rev 0x310, fw ver 34.-1169155311.0, address 90:78:41:39:57:8d > > I don't know yet what's up with that. Also happens on -17 firmware. > The number we show for -34 firmware on 8260 looks OK though. This fixes it and matches what Linux prints: iwm0: hw rev 0x310, fw ver 34.3125811985.0, address 90:78:41:39:57:8d iwlwifi :00:14.3: loaded firmware version 34.3125811985.0 op_mode iwlmvm diff --git sys/dev/pci/if_iwm.c sys/dev/pci/if_iwm.c index 74475da5e58..f6e7c36374c 100644 --- sys/dev/pci/if_iwm.c +++ sys/dev/pci/if_iwm.c @@ -856,7 +856,7 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type) goto parse_out; } snprintf(sc->sc_fwver, sizeof(sc->sc_fwver), - "%d.%d.%d", + "%u.%u.%u", le32toh(((uint32_t *)tlv_data)[0]), le32toh(((uint32_t *)tlv_data)[1]), le32toh(((uint32_t *)tlv_data)[2]));
Re: iwm: support 9260 devices
On Sat, 16 Nov 2019 at 17:09:40 +0100, Stefan Sperling wrote: > On Sat, Nov 16, 2019 at 04:51:44PM +0100, Stefan Sperling wrote: > > This diff adds support for iwm(4) 9260 devices and hopefully 9560 > > devices as well but I have not yet had time to test those. > > > > Joint work with patrick@. Some parts were lifted from FreeBSD. > > > > If you have the followng device in pcidump it should at least get > > an IP address from DHCP and be able to ping: > > 4:0:0: Intel Dual Band Wireless-AC 9260 > > 0x: Vendor ID: 8086, Product ID: 2526 > > > > The firmware is not in fw_update yet. > > In the meantime firmware can be fetched from here: > > https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/ > > > > Copy these files to /etc/firmware as indicated: > > for 9260: iwlwifi-9260-th-b0-jf-b0-34.ucode -> /etc/firmware/iwm-9260-34 > > for 9560: iwlwifi-9000-pu-b0-jf-b0-34.ucode -> /etc/firmware/iwm-9000-34 > > > > Checks for regressions on already supported devices are also welcome, > > in which case the firmware isn't needed. > > Better diff which fixes an Rx throughput issue which was present in > the previous diff. Awesome, thanks guys. It's working great on the 9560 on my ThinkPad X1C7. A speed test showed 44/18 Mbps and it continues to work fine after an S3 cycle. The firmware version string looks odd: iwm0 at pci0 dev 20 function 3 "Intel Dual Band Wireless AC 9560" rev 0x11, msi iwm0: hw rev 0x310, fw ver 34.-1169155311.0, address 90:78:41:39:57:8d
acpithinkpad: don't take over ws_[gs]et_param on version 2 devices
Newer ThinkPads have ACPI goo to allow acpivout to control screen backlight, so don't take over ws_[gs]et_param from it. This allows for 100 levels of backlight control rather than the 10 or 15 that are supported through acpithinkpad using its proprietary ACPI or CMOS interfaces. You can see the difference with and without this patch by doing: xbacklight -set 1 -steps 100 xbacklight -set 100 -steps 100 Apparently this will also be needed for newer AMD ThinkPads that use radeondrm. "Newer" here is being defined as anything not reporting version 1 (THINKPAD_HKEY_VERSION1) of the ThinkPad ACPI interface. For responding to hardware brightness keys, you'll want to test with the acpivout patch I posted since otherwise the keys will be adjusting the backlight by 1% each time, and it may seem like it's not doing anything. That patch makes it properly adjust by 5% each time (but you still get fine-grained changes through wsconsctl or xbacklight). Index: sys/dev/acpi/acpithinkpad.c === RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.66 diff -u -p -u -p -r1.66 acpithinkpad.c --- sys/dev/acpi/acpithinkpad.c 13 Oct 2019 10:56:31 - 1.66 +++ sys/dev/acpi/acpithinkpad.c 14 Oct 2019 02:28:57 - @@ -320,8 +320,10 @@ thinkpad_attach(struct device *parent, s wskbd_set_backlight = thinkpad_set_kbd_backlight; } - if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", - 0, NULL, &sc->sc_brightness) == 0) { + /* On version 2 and newer, let *drm or acpivout control brightness */ + if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION1 && + (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", + 0, NULL, &sc->sc_brightness) == 0)) { ws_get_param = thinkpad_get_param; ws_set_param = thinkpad_set_param; }
acpivout: try to consistently adjust brightness by 5%
When responding to hardware keys to increment or decrement screen brightness, don't just adjust by 1 BCL level as there may be 100 levels. Find the next brightness level that is at least 5% up or down, and use that. Index: dev/acpi/acpivout.c === RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v retrieving revision 1.13 diff -u -p -u -p -r1.13 acpivout.c --- dev/acpi/acpivout.c 13 Oct 2019 10:56:31 - 1.13 +++ dev/acpi/acpivout.c 14 Oct 2019 02:26:12 - @@ -47,6 +47,8 @@ int acpivout_notify(struct aml_node *, i #define NOTIFY_BRIGHTNESS_ZERO 0x88 #define NOTIFY_DISPLAY_OFF 0x89 +#define BRIGHTNESS_STEP5 + struct acpivout_softc { struct device sc_dev; @@ -61,8 +63,7 @@ struct acpivout_softc { }; void acpivout_brightness_cycle(struct acpivout_softc *); -void acpivout_brightness_up(struct acpivout_softc *); -void acpivout_brightness_down(struct acpivout_softc *); +void acpivout_brightness_step(struct acpivout_softc *, int); void acpivout_brightness_zero(struct acpivout_softc *); intacpivout_get_brightness(struct acpivout_softc *); intacpivout_find_brightness(struct acpivout_softc *, int); @@ -128,10 +129,10 @@ acpivout_notify(struct aml_node *node, i acpivout_brightness_cycle(sc); break; case NOTIFY_BRIGHTNESS_UP: - acpivout_brightness_up(sc); + acpivout_brightness_step(sc, 1); break; case NOTIFY_BRIGHTNESS_DOWN: - acpivout_brightness_down(sc); + acpivout_brightness_step(sc, -1); break; case NOTIFY_BRIGHTNESS_ZERO: acpivout_brightness_zero(sc); @@ -158,45 +159,31 @@ acpivout_brightness_cycle(struct acpivou if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1]) acpivout_brightness_zero(sc); else - acpivout_brightness_up(sc); -} - -void -acpivout_brightness_up(struct acpivout_softc *sc) -{ - int i, cur_level; - - if (sc->sc_bcl_len == 0) - return; - cur_level = acpivout_get_brightness(sc); - if (cur_level == -1) - return; - - /* check for max brightness level */ - if (cur_level == sc->sc_bcl[sc->sc_bcl_len - 1]) - return; - - for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++); - acpivout_set_brightness(sc, sc->sc_bcl[i + 1]); + acpivout_brightness_step(sc, 1); } void -acpivout_brightness_down(struct acpivout_softc *sc) +acpivout_brightness_step(struct acpivout_softc *sc, int dir) { - int i, cur_level; + int level, nlevel; if (sc->sc_bcl_len == 0) return; - cur_level = acpivout_get_brightness(sc); - if (cur_level == -1) + level = acpivout_get_brightness(sc); + if (level == -1) return; - /* check for min brightness level */ - if (cur_level == sc->sc_bcl[0]) + nlevel = acpivout_find_brightness(sc, level + (dir * BRIGHTNESS_STEP)); + if (nlevel == level) { + if (dir == 1 && (nlevel + 1 < sc->sc_bcl_len)) + nlevel++; + else if (dir == -1 && (nlevel - 1 >= 0)) + nlevel--; + } + if (nlevel == level) return; - for (i = 0; i < sc->sc_bcl_len && cur_level != sc->sc_bcl[i]; i++); - acpivout_set_brightness(sc, sc->sc_bcl[i - 1]); + acpivout_set_brightness(sc, nlevel); } void
Re: apmd battery emergency message
On Fri, 20 Sep 2019 at 17:00:39 +0200, Alexander Bluhm wrote: > Hi, > > sometimes my laptop was running out of battery while I was working. > To avoid that, I patched apmd(8) to write a emergency message to > syslog(3). Then with this line in syslog.conf I receive a warning > in every xterm. > > # Everyone gets emergency messages. > *.emerg * > > So I have enough time to find a power supply. What about something more generic like a critical action that will run /etc/apm/critical when the battery gets that low, and you can just run "echo low battery | logger -p daemon.emerg" or similar from that script? (I haven't tested this) diff --git usr.sbin/apmd/apmd.8 usr.sbin/apmd/apmd.8 index 84672afbc35..5fab93262ab 100644 --- usr.sbin/apmd/apmd.8 +++ usr.sbin/apmd/apmd.8 @@ -147,8 +147,9 @@ hibernate, standby, resume, powerup, +powerdown, and -powerdown. +critical. The suspend, hibernate and standby actions are run prior to .Nm performing any other actions (such as disk syncs) and entering the new @@ -158,6 +159,8 @@ suspended state. The powerup and powerdown programs are run after the power status (AC connected or not) changes, as well as after a resume (if the power status changed in the mean time). +The critical program is run when the power status is not connected and +the battery reaches a critically low level. .Sh FILES .Bl -tag -width "/etc/apm/powerdownXX" -compact .It Pa /dev/apmctl @@ -169,6 +172,7 @@ Default device used to control the APM kernel driver. .It Pa /etc/apm/resume .It Pa /etc/apm/powerup .It Pa /etc/apm/powerdown +.It Pa /etc/apm/critical These files contain the host's customized actions. Each file must be an executable binary or shell script. A single program or script can be used to control all transitions @@ -179,8 +183,9 @@ hibernate, standby, resume, powerup, +powerdown, or -powerdown. +critical. .Pp .It Pa /var/run/apmdev Default diff --git usr.sbin/apmd/apmd.c usr.sbin/apmd/apmd.c index 1c0f5e03bc9..758a66c1f42 100644 --- usr.sbin/apmd/apmd.c +++ usr.sbin/apmd/apmd.c @@ -196,6 +196,12 @@ power_status(int fd, int force, struct apm_power_info *pinfo) battstate(bstate.battery_state), ac_state(bstate.ac_state), bstate.battery_life); + + if (bstate.battery_state != last.battery_state && + bstate.battery_state == APM_BATT_CRITICAL && + !acon) + do_etc_file(_PATH_APM_ETC_CRITICAL); + last = bstate; } if (pinfo) diff --git usr.sbin/apmd/pathnames.h usr.sbin/apmd/pathnames.h index 2503610404f..ae0ae0e0a98 100644 --- usr.sbin/apmd/pathnames.h +++ usr.sbin/apmd/pathnames.h @@ -38,4 +38,5 @@ #define _PATH_APM_ETC_RESUME _PATH_APM_ETC_DIR"/resume" #define _PATH_APM_ETC_POWERUP _PATH_APM_ETC_DIR"/powerup" #define _PATH_APM_ETC_POWERDOWN_PATH_APM_ETC_DIR"/powerdown" +#define _PATH_APM_ETC_CRITICAL _PATH_APM_ETC_DIR"/critical" #define _PATH_APM_NORMAL "/dev/apm"
azalia: quirk for thinkpad x1c7
The ThinkPad X1 Carbon 7th generation has 4 speakers now, but the default setup connects both speaker and speaker2 to the same DAC. The speaker2 set needs to be routed to a different DAC (dac-0:1) to work properly. This also adds the 300 Series HDA controller to the list of devices where snooping is enabled. Index: sys/dev/pci/azalia.c === RCS file: /cvs/src/sys/dev/pci/azalia.c,v retrieving revision 1.249 diff -u -p -u -p -r1.249 azalia.c --- sys/dev/pci/azalia.c9 May 2019 14:50:46 - 1.249 +++ sys/dev/pci/azalia.c10 Aug 2019 16:22:41 - @@ -453,6 +453,7 @@ azalia_configure_pci(azalia_t *az) case PCI_PRODUCT_INTEL_100SERIES_LP_HDA: case PCI_PRODUCT_INTEL_200SERIES_HDA: case PCI_PRODUCT_INTEL_200SERIES_U_HDA: + case PCI_PRODUCT_INTEL_300SERIES_U_HDA: case PCI_PRODUCT_INTEL_C600_HDA: case PCI_PRODUCT_INTEL_C610_HDA: case PCI_PRODUCT_INTEL_BSW_HDA: @@ -2220,7 +2221,12 @@ azalia_codec_select_spkrdac(codec_t *thi for (i = 0; i < w->nconnections; i++) { conv = azalia_codec_find_defdac(this, w->connections[i], 1); - if (conv == this->spkr_dac) { + if (this->qrks & AZ_QRK_WID_SPKR2_DAC) { + if (conv != this->spkr_dac) { + conn = i; + break; + } + } else if (conv == this->spkr_dac) { conn = i; break; } Index: sys/dev/pci/azalia.h === RCS file: /cvs/src/sys/dev/pci/azalia.h,v retrieving revision 1.66 diff -u -p -u -p -r1.66 azalia.h --- sys/dev/pci/azalia.h24 Mar 2019 14:37:44 - 1.66 +++ sys/dev/pci/azalia.h10 Aug 2019 16:22:41 - @@ -514,6 +514,7 @@ #define AZ_QRK_WID_TPDOCK2 0x0002 #define AZ_QRK_WID_TPDOCK3 0x0004 #define AZ_QRK_WID_DOLBY_ATMOS 0x0010 +#define AZ_QRK_WID_SPKR2_DAC 0x0020 /* memory-mapped types */ typedef struct { Index: sys/dev/pci/azalia_codec.c === RCS file: /cvs/src/sys/dev/pci/azalia_codec.c,v retrieving revision 1.175 diff -u -p -u -p -r1.175 azalia_codec.c --- sys/dev/pci/azalia_codec.c 7 Aug 2019 22:03:43 - 1.175 +++ sys/dev/pci/azalia_codec.c 10 Aug 2019 16:22:42 - @@ -126,6 +126,8 @@ azalia_codec_init_vtbl(codec_t *this) break; case 0x10ec0285: this->name = "Realtek ALC285"; + if (this->subid == 0x229217aa) /* Thinkpad X1 Carbon 7 */ + this->qrks |= AZ_QRK_WID_SPKR2_DAC; break; case 0x10ec0292: this->name = "Realtek ALC292";
ihidev: always register interrupt, stop polling if it fires
The fast polling of ihidev may cause a problem during suspend/resume because dwiic may be in an unknown state, so add a DVACT_QUIESCE handler to properly shut it down. Even if polling is requested, register the interrupt handler too. If it ever fires, stop polling and just use the interrupt. This is what led me to discover that ihidev's interrupt starts firing after a suspend/resume cycle (but I still have no idea why it doesn't work before that). Index: dev/acpi/dwiic_acpi.c === RCS file: /cvs/src/sys/dev/acpi/dwiic_acpi.c,v retrieving revision 1.9 diff -u -p -u -p -r1.9 dwiic_acpi.c --- dev/acpi/dwiic_acpi.c 16 Jul 2019 19:12:32 - 1.9 +++ dev/acpi/dwiic_acpi.c 19 Jul 2019 19:11:21 - @@ -457,8 +457,9 @@ dwiic_acpi_found_ihidev(struct dwiic_sof aml_freevalue(&res); - if (!sc->sc_poll_ihidev && - !(crs.irq_int == 0 && crs.gpio_int_node == NULL)) + if (sc->sc_poll_ihidev) + ia.ia_poll = 1; + if (!(crs.irq_int == 0 && crs.gpio_int_node == NULL)) ia.ia_intr = &crs; if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) { Index: dev/i2c/i2cvar.h === RCS file: /cvs/src/sys/dev/i2c/i2cvar.h,v retrieving revision 1.16 diff -u -p -u -p -r1.16 i2cvar.h --- dev/i2c/i2cvar.h23 Apr 2016 09:40:28 - 1.16 +++ dev/i2c/i2cvar.h19 Jul 2019 19:11:21 - @@ -113,6 +113,7 @@ struct i2c_attach_args { char*ia_name; /* chip name */ void*ia_cookie; /* pass extra info from bus to dev */ void*ia_intr; /* interrupt info */ + int ia_poll;/* to force polling */ }; /* Index: dev/i2c/ihidev.c === RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v retrieving revision 1.19 diff -u -p -u -p -r1.19 ihidev.c --- dev/i2c/ihidev.c8 Apr 2019 17:50:45 - 1.19 +++ dev/i2c/ihidev.c19 Jul 2019 19:11:21 - @@ -63,6 +63,7 @@ static int I2C_HID_POWER_OFF = 0x1; intihidev_match(struct device *, void *, void *); void ihidev_attach(struct device *, struct device *, void *); intihidev_detach(struct device *, int); +intihidev_activate(struct device *, int); intihidev_hid_command(struct ihidev_softc *, int, void *); intihidev_intr(void *); @@ -80,7 +81,7 @@ struct cfattach ihidev_ca = { ihidev_match, ihidev_attach, ihidev_detach, - NULL + ihidev_activate, }; struct cfdriver ihidev_cd = { @@ -128,7 +129,7 @@ ihidev_attach(struct device *parent, str printf(", can't establish interrupt"); } - if (sc->sc_ih == NULL) { + if (ia->ia_poll) { printf(" (polling)"); sc->sc_poll = 1; sc->sc_fastpoll = 1; @@ -227,6 +228,39 @@ ihidev_detach(struct device *self, int f return (0); } +int +ihidev_activate(struct device *self, int act) +{ + struct ihidev_softc *sc = (struct ihidev_softc *)self; + + DPRINTF(("%s(%d)\n", __func__, act)); + + switch (act) { + case DVACT_QUIESCE: + sc->sc_dying = 1; + if (sc->sc_poll && timeout_initialized(&sc->sc_timer)) { + DPRINTF(("%s: canceling polling\n", + sc->sc_dev.dv_xname)); + timeout_del_barrier(&sc->sc_timer); + } + if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, + &I2C_HID_POWER_OFF)) + printf("%s: failed to power down\n", + sc->sc_dev.dv_xname); + break; + case DVACT_WAKEUP: + ihidev_reset(sc); + sc->sc_dying = 0; + if (sc->sc_poll && timeout_initialized(&sc->sc_timer)) + timeout_add(&sc->sc_timer, 2000); + break; + } + + config_activate_children(self, act); + + return 0; +} + void ihidev_sleep(struct ihidev_softc *sc, int ms) { @@ -580,6 +614,16 @@ ihidev_hid_desc_parse(struct ihidev_soft return (0); } +void +ihidev_poll(void *arg) +{ + struct ihidev_softc *sc = arg; + + sc->sc_frompoll = 1; + ihidev_intr(sc); + sc->sc_frompoll = 0; +} + int ihidev_intr(void *arg) { @@ -589,6 +633,16 @@ ihidev_intr(void *arg) u_char *p; u_int rep = 0; + if (sc->sc_dying) + return 1; + + if (sc->sc_poll && !sc->sc_frompoll) { + printf("%s: received interrupt while polling, disabling " + "polling\n", sc->sc_dev.dv_xname); + sc->sc_poll = 0; + timeout_del_barrier(&sc->sc_timer); + } + /* * XXX: force I2C_F_POLL for now to avoid dwiic interrupting
Re: [Patch] Driver for Keyspan USA-19HS
On Mon, 03 Jun 2019 at 23:44:37 -0400, Cody Cutler wrote: > Hi jcs and tech, the following is a patch which implements jcs's feedback and > adds a man page. Thanks Cody, I've imported your driver.
Re: [Patch] Driver for Keyspan USA-19HS
Hi, Some feedback inline: On Tue, 28 May 2019 at 18:42:51 -0400, Cody Cutler wrote: > Hello tech, I'm submitting the following patch for inclusion. The patch > implements a driver for the Keyspan USA-19HS USB-to-serial dongle. > > I've used it for a few months now without any problems. Please let me know if > you spot any problems. > > Thanks! > > diff --git sys/arch/amd64/conf/GENERIC sys/arch/amd64/conf/GENERIC > index ad192f4ea1d..052915d10e0 100644 > --- sys/arch/amd64/conf/GENERIC > +++ sys/arch/amd64/conf/GENERIC > @@ -224,6 +224,8 @@ uvscom* at uhub?# SUNTAC Slipper U > VS-10U serial > ucom*at uvscom? > ubsa*at uhub?# Belkin serial adapter > ucom*at ubsa? > +ukspan* at uhub? # Keyspan USA19HS Nit: maybe add "serial adapter" at the end > +ucom*at ukspan? > uftdi* at uhub?# FTDI FT8U100AX serial adapter > ucom*at uftdi? > uplcom* at uhub? # I/O DATA USB-RSAQ2 serial adapter > diff --git sys/dev/usb/files.usb sys/dev/usb/files.usb > index 1036cf36232..29bc1205540 100644 > --- sys/dev/usb/files.usb > +++ sys/dev/usb/files.usb > @@ -317,6 +317,11 @@ device ubsa: ucombus > attach ubsa at uhub > file dev/usb/ubsa.c ubsa > > +# Keyspan USA19HS serial > +device ukspan: ucombus > +attach ukspan at uhub > +file dev/usb/ukspan.cukspan > + > # Silicon Laboratories CP210x serial > device uslcom: ucombus > attach uslcom at uhub > diff --git sys/dev/usb/ukspan.c sys/dev/usb/ukspan.c > new file mode 100644 > index 000..749144058a0 > --- /dev/null > +++ sys/dev/usb/ukspan.c > @@ -0,0 +1,567 @@ > +#include Please add a copyright and license at the top of the file. /usr/share/misc/license.template is a good one to use. Also, is there any documentation for the device that you used? A URL to it is always useful to include in the header. > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#include > + > +#if 0 > + #define DBG(...) do { printf("ukspan " __VA_ARGS__); } while (0) > +#else > + #define DBG(...) > +#endif Can you put that behind an ifdef UKSPAN_DEBUG and leave a commented out example? That is usually how drivers do it. /* #define UKSPAN_DEBUG */ #ifdef UKSPAN_DEBUG #define DPRINTF(x...) do { printf(x); } while (0); #else #define DPRINTF(x...) #endif > +#define UKSPAN_PARITY_NONE 0x0 > +#define UKSPAN_PARITY_ODD0x08 > +#define UKSPAN_PARITY_EVEN 0x18 > + > +#define UKSPAN_DATA_50x0 > +#define UKSPAN_DATA_60x1 > +#define UKSPAN_DATA_70x2 > +#define UKSPAN_DATA_80x3 > + > +#define UKSPAN_STOP_10x0 > +#define UKSPAN_STOP_20x4 > + > +#define UKSPAN_MAGIC 0x2 > + > +#define UKSPAN_CLOCK 14769231 > + > +/* > + * The following USB endpoint addresses may be specific to the Keyspan > USA19HS > + * device > + */ > +#define UKSPAN_CONFIG_IDX1 > +#define UKSPAN_IFACE_IDX 0 > + > +#define UKSPAN_EA_BULKIN (UE_DIR_IN | 1) > +#define UKSPAN_EA_BULKOUT(UE_DIR_OUT | 1) > +#define UKSPAN_EA_CONFIGIN (UE_DIR_IN | 2) > +#define UKSPAN_EA_CONFIGOUT (UE_DIR_OUT | 2) > + > +/* Sent to device on control out endpoint */ > +struct ukspan_cmsg { > + uint8_t setclock; > + uint8_t baudlo; > + uint8_t baudhi; > + uint8_t setlcr; > + uint8_t lcr; > + uint8_t setrxmode; > + uint8_t rxmode; > + uint8_t settxmode; > + uint8_t txmode; > + uint8_t settxflowcontrol; > + uint8_t txflowcontrol; > + uint8_t setrxflowcontrol; > + uint8_t rxflowcontrol; > + uint8_t sendxoff; > + uint8_t sendxon; > + uint8_t xonchar; > + uint8_t xoffchar; > + uint8_t sendchar; > + uint8_t txchar; > + uint8_t setrts; > + uint8_t rts; > + uint8_t setdtr; > + uint8_t dtr; > + > + uint8_t rxforwardingchars; > + uint8_t rxforwardingtimeoutms; > + uint8_t txacksetting; > + > + uint8_t portenabled; > + uint8_t txflush; > + uint8_t txbreak; > + uint8_t loopbackmode; > + > + uint8_t rxflush; > + uint8_t rxforward; > + uint8_t cancelrxoff; > + uint8_t returnstatus; > +}; > + > +/* Received from device on control in endpoint */ > +struct ukspan_smsg { > + uint8_t msr; > + uint8_t cts; > + uint8_t dcd; > + uint8_t dsr; > + uint8_t ri; > + uint8_t txxoff; > + uint8_t rxbreak; > + uint8_t rxoverrun; > + uint8_t rxparity; > + uint8_t rxframe; > + uint8_t portstate; > + uint8_t messageack; > + uint8_t charack; > + uint8_t controlresp; > +}; If these structures are communicated directly with the device, it's a good idea to make the structs have the __packed attribute. struct ukspan_smsg { ... } __packed; > + > +struct ukspan_softc { > + stru
ubcmtp: fix multi-finger on type4 devices
A previous version of this last year broke on some devices because it tried to pass in pressure data. This version only fixes the padding data of type4 devices. Tested on the 2015 MacBook Pro. Tests on other Apple devices would be appreciated. Index: sys/dev/usb/ubcmtp.c === RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v retrieving revision 1.19 diff -u -p -u -p -r1.19 ubcmtp.c --- sys/dev/usb/ubcmtp.c13 Jan 2019 14:30:16 - 1.19 +++ sys/dev/usb/ubcmtp.c25 May 2019 15:17:00 - @@ -118,6 +118,7 @@ struct ubcmtp_finger { #define UBCMTP_TYPE4_TPLEN UBCMTP_TYPE4_TPOFF + UBCMTP_ALL_FINGER_SIZE #define UBCMTP_TYPE4_TPIFACE 2 #define UBCMTP_TYPE4_BTOFF 31 +#define UBCMTP_TYPE4_FINGERPAD (1 * sizeof(uint16_t)) #define UBCMTP_FINGER_ORIENT 16384 #define UBCMTP_SN_PRESSURE 45 @@ -336,6 +337,7 @@ struct ubcmtp_softc { int sc_tp_epaddr; /* endpoint addr */ int tp_maxlen; /* max size of tp data */ int tp_offset; /* finger offset into data */ + int tp_fingerpad; /* padding between finger data */ uint8_t *tp_pkt; struct usbd_interface *sc_bt_iface; /* button interface */ @@ -429,6 +431,7 @@ ubcmtp_attach(struct device *parent, str sc->sc_udev = uaa->device; sc->sc_status = 0; + sc->tp_fingerpad = 0; if ((udd = usbd_get_device_descriptor(dev)) == NULL) { printf("ubcmtp: failed getting device descriptor\n"); @@ -486,6 +489,7 @@ ubcmtp_attach(struct device *parent, str sc->tp_maxlen = UBCMTP_TYPE4_TPLEN; sc->tp_offset = UBCMTP_TYPE4_TPOFF; sc->sc_tp_iface = uaa->ifaces[UBCMTP_TYPE4_TPIFACE]; + sc->tp_fingerpad = UBCMTP_TYPE4_FINGERPAD; usbd_claim_iface(sc->sc_udev, UBCMTP_TYPE4_TPIFACE); break; } @@ -790,9 +794,9 @@ void ubcmtp_tp_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct ubcmtp_softc *sc = priv; - struct ubcmtp_finger *pkt; + struct ubcmtp_finger *finger; u_int32_t pktlen; - int i, s, btn, contacts, fingers; + int off, s, btn, contacts = 0; if (usbd_is_dying(sc->sc_udev) || !(sc->sc_status & UBCMTP_ENABLED)) return; @@ -813,15 +817,16 @@ ubcmtp_tp_intr(struct usbd_xfer *xfer, v if (sc->tp_pkt == NULL || pktlen < sc->tp_offset) return; - pkt = (struct ubcmtp_finger *)(sc->tp_pkt + sc->tp_offset); - fingers = (pktlen - sc->tp_offset) / sizeof(struct ubcmtp_finger); - contacts = 0; - for (i = 0; i < fingers; i++) { - if ((int16_t)letoh16(pkt[i].touch_major) == 0) + for (off = sc->tp_offset; off < pktlen; + off += (sizeof(struct ubcmtp_finger) + sc->tp_fingerpad)) { + finger = (struct ubcmtp_finger *)(sc->tp_pkt + off); + + if ((int16_t)letoh16(finger->touch_major) == 0) continue; /* finger lifted */ - sc->frame[contacts].x = (int16_t)letoh16(pkt[i].abs_x); - sc->frame[contacts].y = (int16_t)letoh16(pkt[i].abs_y); + + sc->frame[contacts].x = (int16_t)letoh16(finger->abs_x); + sc->frame[contacts].y = (int16_t)letoh16(finger->abs_y); sc->frame[contacts].pressure = DEFAULT_PRESSURE; contacts++; }
ihidev: fix possible panic
psize is built from the first two bytes read from the device, but it could be completely bogus, especially when polling. This can result in a panic when reading p. Promote it to a signed int to catch it going negative and discard it if it's 2 or less, because shortly after it is decreased by 2 or 3. Index: sys/dev/i2c/ihidev.c === RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v retrieving revision 1.18 diff -u -p -u -p -r1.18 ihidev.c --- sys/dev/i2c/ihidev.c20 Sep 2018 01:19:56 - 1.18 +++ sys/dev/i2c/ihidev.c8 Apr 2019 14:42:53 - @@ -585,8 +585,7 @@ ihidev_intr(void *arg) { struct ihidev_softc *sc = arg; struct ihidev *scd; - u_int psize; - int res, i, fast = 0; + int psize, res, i, fast = 0; u_char *p; u_int rep = 0; @@ -605,7 +604,7 @@ ihidev_intr(void *arg) * than or equal to wMaxInputLength */ psize = sc->sc_ibuf[0] | sc->sc_ibuf[1] << 8; - if (!psize || psize > sc->sc_isize) { + if (psize <= 2 || psize > sc->sc_isize) { if (sc->sc_poll) { /* * TODO: all fingers are up, should we pass to hid
Re: wscons: precision scrolling
On Sun, 17 Mar 2019 at 19:35:17 +0100, Ulf Brosziewski wrote: > Hi Joshua, > > could you make a test with the updated diff below and check whether > the scroll speed is normal? (There are no changes in ws, it's just > the kernel part). Hi, this version scrolls much better.
ihidev: always register interrupt
I still haven't figured out why ihidev doesn't receive interrupts for I2C devices on Intel 100 series and newer. But on an Intel 300 series laptop, I noticed that the Elan touchscreen (ims at ihidev) does actually generate interrupts while the Elan touchpad (imt at ihidev) doesn't. In this scenario, we can disable polling on the touchscreen to save some power and make input smoother. This diff always sets up the interrupt even when polling is requested, and if the interrupt handler ever fires when polling is enabled, disable polling. Index: dev/acpi/dwiic_acpi.c === RCS file: /cvs/src/sys/dev/acpi/dwiic_acpi.c,v retrieving revision 1.8 diff -u -p -u -p -r1.8 dwiic_acpi.c --- dev/acpi/dwiic_acpi.c 1 Jul 2018 11:37:11 - 1.8 +++ dev/acpi/dwiic_acpi.c 16 Mar 2019 15:39:34 - @@ -462,8 +462,9 @@ dwiic_acpi_found_ihidev(struct dwiic_sof aml_freevalue(&res); - if (!sc->sc_poll_ihidev && - !(crs.irq_int == 0 && crs.gpio_int_node == NULL)) + if (sc->sc_poll_ihidev) + ia.ia_poll = 1; + if (!(crs.irq_int == 0 && crs.gpio_int_node == NULL)) ia.ia_intr = &crs; if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) { Index: dev/i2c/i2cvar.h === RCS file: /cvs/src/sys/dev/i2c/i2cvar.h,v retrieving revision 1.16 diff -u -p -u -p -r1.16 i2cvar.h --- dev/i2c/i2cvar.h23 Apr 2016 09:40:28 - 1.16 +++ dev/i2c/i2cvar.h16 Mar 2019 15:39:34 - @@ -113,6 +113,7 @@ struct i2c_attach_args { char*ia_name; /* chip name */ void*ia_cookie; /* pass extra info from bus to dev */ void*ia_intr; /* interrupt info */ + int ia_poll;/* to force polling */ }; /* Index: dev/i2c/ihidev.c === RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v retrieving revision 1.18 diff -u -p -u -p -r1.18 ihidev.c --- dev/i2c/ihidev.c20 Sep 2018 01:19:56 - 1.18 +++ dev/i2c/ihidev.c16 Mar 2019 15:39:34 - @@ -128,7 +128,7 @@ ihidev_attach(struct device *parent, str printf(", can't establish interrupt"); } - if (sc->sc_ih == NULL) { + if (ia->ia_poll) { printf(" (polling)"); sc->sc_poll = 1; sc->sc_fastpoll = 1; @@ -580,6 +580,16 @@ ihidev_hid_desc_parse(struct ihidev_soft return (0); } +void +ihidev_poll(void *arg) +{ + struct ihidev_softc *sc = arg; + + sc->sc_dopoll = 1; + ihidev_intr(sc); + sc->sc_dopoll = 0; +} + int ihidev_intr(void *arg) { @@ -590,6 +600,13 @@ ihidev_intr(void *arg) u_char *p; u_int rep = 0; + if (sc->sc_poll && !sc->sc_dopoll) { + printf("%s: received interrupt while polling, disabling " + "polling\n", sc->sc_dev.dv_xname); + sc->sc_poll = 0; + timeout_del(&sc->sc_timer); + } + /* * XXX: force I2C_F_POLL for now to avoid dwiic interrupting * while we are interrupting @@ -741,7 +758,7 @@ ihidev_open(struct ihidev *scd) if (sc->sc_poll) { if (!timeout_initialized(&sc->sc_timer)) - timeout_set(&sc->sc_timer, (void *)ihidev_intr, sc); + timeout_set(&sc->sc_timer, (void *)ihidev_poll, sc); if (!timeout_pending(&sc->sc_timer)) timeout_add(&sc->sc_timer, FAST_POLL_MS); } Index: dev/i2c/ihidev.h === RCS file: /cvs/src/sys/dev/i2c/ihidev.h,v retrieving revision 1.6 diff -u -p -u -p -r1.6 ihidev.h --- dev/i2c/ihidev.h25 Aug 2018 18:32:05 - 1.6 +++ dev/i2c/ihidev.h16 Mar 2019 15:39:34 - @@ -89,6 +89,7 @@ struct ihidev_softc { int sc_refcnt; int sc_poll; + int sc_dopoll; int sc_fastpoll; struct timeout sc_timer; };
Re: wscons: precision scrolling
On Thu, 14 Mar 2019 at 00:48:33 +0100, Ulf Brosziewski wrote: > Much too fast? I'm a bit surprised. In my tests, the new method was > generally somewhat slower than the old one (and I haven't changed the > "scroll units"). How did you test it? Which hardware and which applications > did you use? This is with an imt touchpad: ihidev0 at iic1 addr 0x15 irq 109 (polling), vendor 0x4f3 product 0x3056, ELAN2201 ihidev0: 93 report ids imt0 at ihidev0: clickpad, 5 contacts wsmouse0 at imt0 mux 0 I tested with two-finger scrolling in Firefox and Chrome with a new user and fresh browser profiles. I loaded the same webpages with the old wstpad code and the new, and the two-finger scrolling with the new setup scrolls much too fast for even small finger movements (~0.5"). A movement with the previous code that would trigger the mousewheel-style scrolling of just a handful of lines causes the new code to scroll nearly an entire screen-height of the page.
dwiic at pci: fetch timing parameters from acpi
While making dwiic at pci attach on an Intel 300 series laptop, dwiic was timing out while ihidev tried to fetch the HID descriptor. Turns out the default timing parameters pulled from the device are wrong, so try to fetch them from ACPI and use those instead. This matches what dwiic at acpi does. If you have a device where dwiic fails in this way, this may fix the problem for you. dwiic0 at pci0 dev 21 function 0 "Intel 300 Series I2C" rev 0x30: apic 2 int 16 iic0 at dwiic0 ihidev0 at iic0 addr 0x15dwiic0: timed out reading remaining 29 , failed fetching initial HID descriptor Index: sys/dev/pci/dwiic_pci.c === RCS file: /cvs/src/sys/dev/pci/dwiic_pci.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 dwiic_pci.c --- sys/dev/pci/dwiic_pci.c 12 Jan 2018 08:11:48 - 1.3 +++ sys/dev/pci/dwiic_pci.c 15 Mar 2019 21:04:46 - @@ -62,6 +62,12 @@ struct cfattach dwiic_pci_ca = { const struct pci_matchid dwiic_pci_ids[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_I2C_1 }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_I2C_2 }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_1 }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_2 }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_3 }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_4 }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_5 }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_6 }, }; int @@ -75,6 +81,9 @@ dwiic_pci_attach(struct device *parent, { struct dwiic_softc *sc = (struct dwiic_softc *)self; struct pci_attach_args *pa = aux; +#if NACPI > 0 + struct aml_node *node; +#endif bus_size_t iosize; pci_intr_handle_t ih; const char *intrstr = NULL; @@ -109,6 +118,19 @@ dwiic_pci_attach(struct device *parent, sc->fs_lcnt = dwiic_read(sc, DW_IC_FS_SCL_LCNT); sc->sda_hold_time = dwiic_read(sc, DW_IC_SDA_HOLD); +#if NACPI > 0 + /* fetch more accurate timing parameters from ACPI, if possible */ + node = acpi_pci_match(self, &sc->sc_paa); + if (node != NULL) { + sc->sc_devnode = node; + + dwiic_acpi_get_params(sc, "SSCN", &sc->ss_hcnt, &sc->ss_lcnt, + NULL); + dwiic_acpi_get_params(sc, "FMCN", &sc->fs_hcnt, &sc->fs_lcnt, + &sc->sda_hold_time); + } +#endif + if (dwiic_init(sc)) { printf(": failed initializing\n"); return; @@ -184,12 +206,7 @@ dwiic_pci_bus_scan(struct device *iic, s sc->sc_iic = iic; -#if NACPI > 0 - { - struct aml_node *node = acpi_pci_match(aux, &sc->sc_paa); - if (node == NULL) - return; - + if (sc->sc_devnode != NULL) { /* * XXX: until we can figure out why interrupts don't arrive for * i2c slave devices on intel 100 series and newer, force @@ -197,7 +214,6 @@ dwiic_pci_bus_scan(struct device *iic, s */ sc->sc_poll_ihidev = 1; - aml_find_node(node, "_HID", dwiic_acpi_found_hid, sc); + aml_find_node(sc->sc_devnode, "_HID", dwiic_acpi_found_hid, sc); } -#endif } Index: sys/dev/ic/dwiicvar.h === RCS file: /cvs/src/sys/dev/ic/dwiicvar.h,v retrieving revision 1.2 diff -u -p -u -p -r1.2 dwiicvar.h --- sys/dev/ic/dwiicvar.h 19 Jan 2018 18:20:38 - 1.2 +++ sys/dev/ic/dwiicvar.h 15 Mar 2019 21:04:46 - @@ -34,6 +34,8 @@ #include +#include "acpi.h" + /* #define DWIIC_DEBUG */ #ifdef DWIIC_DEBUG @@ -99,4 +101,8 @@ void dwiic_write(struct dwiic_softc *, intdwiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, void *, size_t, int); -intdwiic_acpi_found_hid(struct aml_node *node, void *arg); +#if NACPI > 0 +intdwiic_acpi_found_hid(struct aml_node *, void *); +void dwiic_acpi_get_params(struct dwiic_softc *, char *, uint16_t *, + uint16_t *, uint32_t *); +#endif
Re: wscons: precision scrolling
On Wed, 13 Mar 2019 at 00:41:12 +0100, Ulf Brosziewski wrote: > The standard method of scrolling in X is tailored to mouse wheels and > proceeds in coarse steps. Wheel events are mapped to button events, and on > receiving such an event, an application moves the view of its data by some > fixed distance - usually the height of a line of text, or of a couple of > lines. > > Version 2.1 of the X Input Protocol has introduced a more precise > alternative. It defines additional types of motion events. In essence, > their values represent fractions of a complete scroll unit, and newer > applications may move their views by distances that are proportional to the > event values. For applications that don't support this, X generates the > standard button events whenever the values add up to the complete unit. > > synaptics(4) supports the newer method since long. > > The diffs below add the feature to ws and wstpad. The kernel part defines > two new event types in wsconsio.h, and it adapts the scrolling functions of > the touchpad input driver. The xenocara part adds the new "axes" and event > handlers to ws. > > There is a little twist to the implementation. While synaptics(4) > initializes the scroll axes with the scroll distance in device units, the > constant 4096 is used in the new ws code, and event values represent the > fraction (motion_delta / scroll_unit) in [*.12] fixed-point format. That > way, no queries for the device- and configuration-dependent scroll unit > are necessary. > > The X Input Protocol calls the method "smooth scrolling", but it seems > that nowadays, this term is used exclusively for the rendering technique > that displays a little animation when the document position changes, so > "precision scrolling" might be a better choice. > > Tests, comments, and OKs would be welcome. Well done! It works on my touchpad and retains the old "chunky" style scrolling from the mouse wheel on my external mouse. My only quibble is that this new style scrolling seems much too fast by default with the default X and wscons mouse acceleration settings.
acpithinkpad: a fix for the x260
sthen found that the HKEY version metric failed on the x260 where it reports version 1 but requires the new ACPI method of changing backlight. This diff tries to do the ACPI method on all machines and falls back to the CMOS method if that fails. Can all those that tried the previous diff (which has been committed) try this one and make sure nothing broke? This also unmasks the microphone mute event which helps mixerctl stay in sync on the x260 (it has no effect on my x1c6, but probably can't hurt). Index: sys/dev/acpi/acpithinkpad.c === RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.63 diff -u -p -u -p -r1.63 acpithinkpad.c --- sys/dev/acpi/acpithinkpad.c 6 Mar 2019 15:36:30 - 1.63 +++ sys/dev/acpi/acpithinkpad.c 7 Mar 2019 02:53:36 - @@ -124,6 +124,7 @@ #define THINKPAD_ADAPTIVE_MODE_HOME 1 #define THINKPAD_ADAPTIVE_MODE_FUNCTION 3 +#define THINKPAD_MASK_MIC_MUTE (1 << 14) #define THINKPAD_MASK_BRIGHTNESS_UP (1 << 15) #define THINKPAD_MASK_BRIGHTNESS_DOWN (1 << 16) #define THINKPAD_MASK_KBD_BACKLIGHT (1 << 17) @@ -171,8 +172,8 @@ int thinkpad_get_kbd_backlight(struct ws int thinkpad_set_kbd_backlight(struct wskbd_backlight *); extern int (*wskbd_get_backlight)(struct wskbd_backlight *); extern int (*wskbd_set_backlight)(struct wskbd_backlight *); -void thinkpad_get_brightness(struct acpithinkpad_softc *); -void thinkpad_set_brightness(void *, int); +intthinkpad_get_brightness(struct acpithinkpad_softc *); +intthinkpad_set_brightness(void *, int); int thinkpad_get_param(struct wsdisplay_param *); int thinkpad_set_param(struct wsdisplay_param *); extern int (*ws_get_param)(struct wsdisplay_param *); @@ -345,7 +346,9 @@ thinkpad_enable_events(struct acpithinkp } /* Enable events we need to know about */ - mask |= (THINKPAD_MASK_BRIGHTNESS_UP | THINKPAD_MASK_BRIGHTNESS_DOWN | + mask |= (THINKPAD_MASK_MIC_MUTE | + THINKPAD_MASK_BRIGHTNESS_UP | + THINKPAD_MASK_BRIGHTNESS_DOWN | THINKPAD_MASK_KBD_BACKLIGHT); DPRINTF(("%s: setting event mask to 0x%llx\n", DEVNAME(sc), mask)); @@ -555,8 +558,7 @@ thinkpad_brightness_up(struct acpithinkp { int b; - if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION2) { - thinkpad_get_brightness(sc); + if (thinkpad_get_brightness(sc) == 0) { b = sc->sc_brightness & 0xff; if (b < ((sc->sc_brightness >> 8) & 0xff)) { sc->sc_brightness = b + 1; @@ -573,8 +575,7 @@ thinkpad_brightness_down(struct acpithin { int b; - if (sc->sc_hkey_version == THINKPAD_HKEY_VERSION2) { - thinkpad_get_brightness(sc); + if (thinkpad_get_brightness(sc) == 0) { b = sc->sc_brightness & 0xff; if (b > 0) { sc->sc_brightness = b - 1; @@ -701,30 +702,39 @@ thinkpad_set_kbd_backlight(struct wskbd_ return 0; } -void +int thinkpad_get_brightness(struct acpithinkpad_softc *sc) { - aml_evalinteger(sc->sc_acpi, sc->sc_devnode, - "PBLG", 0, NULL, &sc->sc_brightness); + int ret; + + ret = aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", 0, NULL, + &sc->sc_brightness); DPRINTF(("%s: %s: 0x%llx\n", DEVNAME(sc), __func__, sc->sc_brightness)); + + return ret; } -void +int thinkpad_set_brightness(void *arg0, int arg1) { struct acpithinkpad_softc *sc = arg0; struct aml_value arg; + int ret; DPRINTF(("%s: %s: 0x%llx\n", DEVNAME(sc), __func__, sc->sc_brightness)); memset(&arg, 0, sizeof(arg)); arg.type = AML_OBJTYPE_INTEGER; arg.v_integer = sc->sc_brightness & 0xff; - aml_evalname(sc->sc_acpi, sc->sc_devnode, - "PBLS", 1, &arg, NULL); + ret = aml_evalname(sc->sc_acpi, sc->sc_devnode, "PBLS", 1, &arg, NULL); + + if (ret) + return ret; thinkpad_get_brightness(sc); + + return 0; } int @@ -765,7 +775,8 @@ thinkpad_set_param(struct wsdisplay_para dp->curval = maxval; sc->sc_brightness &= ~0xff; sc->sc_brightness |= dp->curval; - acpi_addtask(sc->sc_acpi, thinkpad_set_brightness, sc, 0); + acpi_addtask(sc->sc_acpi, (void *)thinkpad_set_brightness, sc, + 0); acpi_wakeup(sc->sc_acpi); return 0; default:
acpithinkpad: fix brightness keys, keyboard backlight value
Here we go again... On at least the ThinkPad X1C6, the screen brightness keys (F5 and F6) do not work and "wsconsctl keyboard.backlight" doesn't report the correct value when the keyboard backlight is adjusted with Fn+Space. These are both caused by the default event mask not including these events, so explicitly enable them. But then acpithinkpad has to actually do something for the screen brightness keys, but it tries the very old CMOS method which doesn't work on these newer machines[0]. So make it use the ACPI method. I renamed thinkpad_[gs]et_backlight to thinkpad_[gs]et_kbd_backlight because it was confusing that they have nothing to do with screen backlight. 0. "newer machines" being those with MHKV reporting version 2. If this diff breaks on older "newer machines", this metric will have to be changed to something else. Index: sys/dev/acpi/acpithinkpad.c === RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.61 diff -u -p -u -p -r1.61 acpithinkpad.c --- sys/dev/acpi/acpithinkpad.c 1 Jul 2018 19:40:49 - 1.61 +++ sys/dev/acpi/acpithinkpad.c 5 Mar 2019 20:00:23 - @@ -124,6 +124,10 @@ #defineTHINKPAD_ADAPTIVE_MODE_HOME 1 #defineTHINKPAD_ADAPTIVE_MODE_FUNCTION 3 +#define THINKPAD_MASK_BRIGHTNESS_UP(1 << 15) +#define THINKPAD_MASK_BRIGHTNESS_DOWN (1 << 16) +#define THINKPAD_MASK_KBD_BACKLIGHT(1 << 17) + struct acpithinkpad_softc { struct devicesc_dev; @@ -134,6 +138,8 @@ struct acpithinkpad_softc { struct ksensor sc_sens[THINKPAD_NSENSORS]; struct ksensordevsc_sensdev; + uint64_t sc_hkey_version; + uint64_t sc_thinklight; const char *sc_thinklight_get; const char *sc_thinklight_set; @@ -161,8 +167,8 @@ int thinkpad_activate(struct device *, i /* wscons hook functions */ void thinkpad_get_thinklight(struct acpithinkpad_softc *); void thinkpad_set_thinklight(void *, int); -intthinkpad_get_backlight(struct wskbd_backlight *); -intthinkpad_set_backlight(struct wskbd_backlight *); +intthinkpad_get_kbd_backlight(struct wskbd_backlight *); +intthinkpad_set_kbd_backlight(struct wskbd_backlight *); extern int (*wskbd_get_backlight)(struct wskbd_backlight *); extern int (*wskbd_set_backlight)(struct wskbd_backlight *); void thinkpad_get_brightness(struct acpithinkpad_softc *); @@ -284,6 +290,10 @@ thinkpad_attach(struct device *parent, s printf("\n"); + if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKV", 0, NULL, + &sc->sc_hkey_version)) + sc->sc_hkey_version = THINKPAD_HKEY_VERSION1; + #if NAUDIO > 0 && NWSKBD > 0 /* Defer speaker mute */ if (thinkpad_get_volume_mute(sc) == 1) @@ -299,14 +309,14 @@ thinkpad_attach(struct device *parent, s 0, NULL, &sc->sc_thinklight) == 0) { sc->sc_thinklight_get = "KLCG"; sc->sc_thinklight_set = "KLCS"; - wskbd_get_backlight = thinkpad_get_backlight; - wskbd_set_backlight = thinkpad_set_backlight; + wskbd_get_backlight = thinkpad_get_kbd_backlight; + wskbd_set_backlight = thinkpad_set_kbd_backlight; } else if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MLCG", 0, NULL, &sc->sc_thinklight) == 0) { sc->sc_thinklight_get = "MLCG"; sc->sc_thinklight_set = "MLCS"; - wskbd_get_backlight = thinkpad_get_backlight; - wskbd_set_backlight = thinkpad_set_backlight; + wskbd_get_backlight = thinkpad_get_kbd_backlight; + wskbd_set_backlight = thinkpad_set_kbd_backlight; } if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", @@ -327,13 +337,19 @@ thinkpad_enable_events(struct acpithinkp int64_t mask; int i; - /* Get the supported event mask */ + /* Get the default event mask */ if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKA", 0, NULL, &mask)) { printf("%s: no MHKA\n", DEVNAME(sc)); return (1); } + /* Enable events we need to know about */ + mask |= (THINKPAD_MASK_BRIGHTNESS_UP | THINKPAD_MASK_BRIGHTNESS_DOWN | + THINKPAD_MASK_KBD_BACKLIGHT); + + DPRINTF(("%s: setting event mask to 0x%llx\n", DEVNAME(sc), mask)); + /* Update hotkey mask */ bzero(args, sizeof(args)); args[0].type = args[1].type = AML_OBJTYPE_INTEGER; @@ -380,6 +396,8 @@ thinkpad_hotkey(struct aml_node *node, i if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKP", 0, NULL, &event)) break; + + DPRINTF(("%s: event 0x%03llx\n", DEVNAME(sc), event)); if (event == 0)
Re: [PATCH] Add elan(4) touchpad driver
On Fri, 09 Nov 2018 at 03:30:07 +, b...@curlybracket.co.uk wrote: > Hi all, > > This patch adds a new touchpad driver, elan(4), which supports older non > PTP I2C Elantech touchpads. I have tested this on my HP Chromebook 13 > and it appears to work well, multitouch is working as well as the three > physical mouse buttons. I do not know how well this will work on other > Elantech touchpads however; I believe there are a few devices that use > the same protocol though they may have different ACPI hids. > > This driver is similar to iatp(4) and is largely based upon it although > the actual protocol used by the touchpad is quite different. > > I have added a basic man page following iatp(4) as a guide. I wasn't > sure if I should add the copyright and OpenBSD headers and so for this > first patch I have omitted them. > > This together with my previous sdhc(4) patch results in a mostly working > OpenBSD install on the HP Chromebook 13, unfortunately apm(4) is still > problematic and the device gets stuck in sleep. Hi, Well done! The code looks mostly ok. There are a bunch of 8-space indentations instead of tabs that need to be fixed. You should include a comment header with your copyright and a license, preferably /usr/share/misc/license.template. We have a habit of naming USB and i2c devices starting with 'u' and 'i', and since there is already a bunch of Elantech touchpad device support in pms(4), it would be best to rename this from 'elan' to something more narrow. Maybe ietp (since iatp is for i2c Atmel touchpads) or ielantp or something. As for the driver itself, is this implementing a specific protocol version for Elantech devices like the four in pms(4)? If this driver is limited to a specific protocol version or model, it would be beneficial to mention that in the driver code and man page. > Index: sys/arch/amd64/conf/GENERIC > === > RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v > retrieving revision 1.464 > diff -u -p -r1.464 GENERIC > --- sys/arch/amd64/conf/GENERIC 26 Oct 2018 20:26:19 - 1.464 > +++ sys/arch/amd64/conf/GENERIC 9 Nov 2018 03:25:17 - > @@ -177,6 +177,8 @@ imt* at ihidev? # HID-over-i2c multitou > wsmouse* at imt? mux 0 > iatp* at iic?# Atmel maXTouch i2c > touchpad/touchscreen > wsmouse* at iatp? mux 0 > +elan* at iic?# Elantech i2c touchpad > +wsmouse* at elan? mux 0 > > skgpio0 at isa? port 0x680 # Soekris net6501 GPIO and LEDs > gpio* at skgpio? > Index: sys/dev/acpi/dwiic_acpi.c > === > RCS file: /cvs/src/sys/dev/acpi/dwiic_acpi.c,v > retrieving revision 1.8 > diff -u -p -r1.8 dwiic_acpi.c > --- sys/dev/acpi/dwiic_acpi.c 1 Jul 2018 11:37:11 - 1.8 > +++ sys/dev/acpi/dwiic_acpi.c 9 Nov 2018 03:25:18 - > @@ -51,6 +51,8 @@ int dwiic_acpi_found_ihidev(struct dwii > struct aml_node *, char *, struct dwiic_crs); > int dwiic_acpi_found_iatp(struct dwiic_softc *, struct aml_node *, > char *, struct dwiic_crs); > +int dwiic_acpi_found_elan(struct dwiic_softc *, struct aml_node *, > + char *, struct dwiic_crs); > void dwiic_acpi_get_params(struct dwiic_softc *, char *, uint16_t *, > uint16_t *, uint32_t *); > void dwiic_acpi_power(struct dwiic_softc *, int); > @@ -87,6 +89,11 @@ const char *iatp_hids[] = { > NULL > }; > > +const char *elan_hids[] = { > + "ELAN", > + NULL > +}; > + > int > dwiic_acpi_match(struct device *parent, void *match, void *aux) > { > @@ -388,6 +395,8 @@ dwiic_acpi_found_hid(struct aml_node *no > return dwiic_acpi_found_ihidev(sc, node, dev, crs); > else if (dwiic_matchhids(dev, iatp_hids)) > return dwiic_acpi_found_iatp(sc, node, dev, crs); > + else if (dwiic_matchhids(dev, elan_hids)) > + return dwiic_acpi_found_elan(sc, node, dev, crs); > > memset(&ia, 0, sizeof(ia)); > ia.ia_tag = sc->sc_iba.iba_tag; > @@ -489,6 +498,34 @@ dwiic_acpi_found_iatp(struct dwiic_softc > ia.ia_tag = sc->sc_iba.iba_tag; > ia.ia_size = 1; > ia.ia_name = "iatp"; > + ia.ia_addr = crs.i2c_addr; > + ia.ia_cookie = dev; > + > + if (crs.irq_int <= 0 && crs.gpio_int_node == NULL) { > + printf("%s: couldn't find irq for %s\n", sc->sc_dev.dv_xname, > +aml_nodename(node->parent)); > + return 0; > + } > + ia.ia_intr = &crs; > + > + if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) { > + node->parent->attached = 1; > + return 0; > + } > + > + return 1; > +} > + > +int > +dwiic_acpi_found_elan(struct dwiic_softc *sc, struct aml_node *node, char > *dev, > +struct dwiic_crs crs) > +{ > + struct i2c_attach_args
Re: ims: match on HID touchscreens
On Sat, 01 Sep 2018 at 20:53:45 +0200, Mark Kettenis wrote: > Not sure if that is indeed the right approach, but we can always fix > it in a better way later. The HID report descriptor contains this: [...] 0x05, 0x01,// Usage Page (Generic Desktop Ctrls) 0x09, 0x30,// Usage (X) 0x75, 0x10,// Report Size (16) 0x95, 0x01,// Report Count (1) 0xA4, // Push 0x55, 0x0F,// Unit Exponent (-1) 0x65, 0x11,// Unit (System: SI Linear, Length: Centimeter) 0x46, 0xD3, 0x00, // Physical Maximum (211) 0x26, 0x00, 0x34, // Logical Maximum (13312) 0x81, 0x42,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State) 0x09, 0x31,// Usage (Y) 0x46, 0x8D, 0x00, // Physical Maximum (141) 0x26, 0x00, 0x23, // Logical Maximum (8960) 0x81, 0x42,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State) 0xB4, // Pop So it matched HUP_GENERIC_DESKTOP and was setting the logical maximums to 13312/8960, but that chunk is nested in other collections. I'm not sure how our HID Parser is supposed to deal with that. Here's the full HID report descriptor from the i2c touchscreen: 0x05, 0x0D,// Usage Page (Digitizer) 0x09, 0x04,// Usage (Touch Screen) 0xA1, 0x01,// Collection (Application) 0x85, 0x01,// Report ID (1) 0x09, 0x22,// Usage (Finger) 0xA1, 0x02,// Collection (Logical) 0x09, 0x42,// Usage (Tip Switch) 0x15, 0x00,// Logical Minimum (0) 0x25, 0x01,// Logical Maximum (1) 0x75, 0x01,// Report Size (1) 0x95, 0x01,// Report Count (1) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x01,// Report Size (1) 0x81, 0x03,// Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x06,// Report Size (6) 0x09, 0x51,// Usage (0x51) 0x25, 0x3F,// Logical Maximum (63) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08,// Report Size (8) 0x09, 0x48,// Usage (0x48) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x09, 0x49,// Usage (0x49) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x01,// Report Count (1) 0x05, 0x01,// Usage Page (Generic Desktop Ctrls) 0xA4, // Push 0x26, 0xC0, 0x09, // Logical Maximum (2496) 0x75, 0x10,// Report Size (16) 0x55, 0x0F,// Unit Exponent (-1) 0x65, 0x11,// Unit (System: SI Linear, Length: Centimeter) 0x09, 0x30,// Usage (X) 0x35, 0x00,// Physical Minimum (0) 0x46, 0xD3, 0x00, // Physical Maximum (211) 0x95, 0x02,// Report Count (2) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x26, 0x90, 0x06, // Logical Maximum (1680) 0x46, 0x8D, 0x00, // Physical Maximum (141) 0x09, 0x31,// Usage (Y) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xB4, // Pop 0xC0, // End Collection 0x05, 0x0D,// Usage Page (Digitizer) 0x09, 0x22,// Usage (Finger) 0xA1, 0x02,// Collection (Logical) 0x05, 0x0D,// Usage Page (Digitizer) 0x09, 0x42,// Usage (Tip Switch) 0x15, 0x00,// Logical Minimum (0) 0x25, 0x01,// Logical Maximum (1) 0x75, 0x01,// Report Size (1) 0x95, 0x01,// Report Count (1) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x01,// Report Size (1) 0x81, 0x03,// Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x75, 0x06,// Report Size (6) 0x09, 0x51,// Usage (0x51) 0x25, 0x3F,// Logical Maximum (63) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08,// Report Size (8) 0x09, 0x48,// Usage (0x48) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x09, 0x49,// Usage (0x49) 0x81, 0x02,// Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x01,// Report Count (1) 0x05, 0x01,// Usage Page (Generic Desktop Ctrls) 0xA4, // Push 0x26, 0xC0, 0x09, // Logical Maximum (2496) 0x75, 0x10,// Report Size (16) 0x55, 0x0F,// Unit Exponent (-
ims: match on HID touchscreens
If there is an i2c HID device that has a Digitizers/Touchscreen collection and an X report, attach ims to it. hidms already has support for touchscreens. This may help if you have a newer laptop with a touchscreen. Also limit the logical min/max finding in hidms to the first non-zero result. The HID descriptor for these touchscreens have lots of complicated reports which may produce false positives. Index: sys/dev/i2c/ims.c === RCS file: /cvs/src/sys/dev/i2c/ims.c,v retrieving revision 1.1 diff -u -p -u -p -r1.1 ims.c --- sys/dev/i2c/ims.c 12 Jan 2016 01:11:15 - 1.1 +++ sys/dev/i2c/ims.c 31 Aug 2018 21:42:30 - @@ -85,6 +85,12 @@ ims_match(struct device *parent, void *m HID_USAGE2(HUP_DIGITIZERS, HUD_PEN))) return (IMATCH_IFACECLASS); + if (hid_is_collection(desc, size, iha->reportid, + HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHSCREEN)) && + hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), + iha->reportid, hid_input, NULL, NULL)) + return (IMATCH_IFACECLASS); + return (IMATCH_NONE); } Index: sys/dev/hid/hidms.c === RCS file: /cvs/src/sys/dev/hid/hidms.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 hidms.c --- sys/dev/hid/hidms.c 22 May 2016 22:06:11 - 1.3 +++ sys/dev/hid/hidms.c 31 Aug 2018 21:42:30 - @@ -241,13 +241,15 @@ hidms_setup(struct device *self, struct h.usage, h.logical_minimum, h.logical_maximum)); switch (HID_GET_USAGE(h.usage)) { case HUG_X: - if (ms->sc_flags & HIDMS_ABSX) { + if (ms->sc_flags & HIDMS_ABSX && + !ms->sc_tsscale.minx && !ms->sc_tsscale.maxy) { ms->sc_tsscale.minx = h.logical_minimum; ms->sc_tsscale.maxx = h.logical_maximum; } break; case HUG_Y: - if (ms->sc_flags & HIDMS_ABSY) { + if (ms->sc_flags & HIDMS_ABSY && + !ms->sc_tsscale.miny && !ms->sc_tsscale.maxy) { ms->sc_tsscale.miny = h.logical_minimum; ms->sc_tsscale.maxy = h.logical_maximum; }
umt(4)
For USB-connected Windows Precision Touchpad devices, just like imt(4) is for i2c. Also renames HIDMT_INPUT_MODE_MT to HIDMT_INPUT_MODE_MT_TOUCHPAD since there is a different value for touchscreens (not yet used). Index: sys/arch/amd64/conf/GENERIC === RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v retrieving revision 1.460 diff -u -p -u -p -r1.460 GENERIC --- sys/arch/amd64/conf/GENERIC 22 Aug 2018 15:38:46 - 1.460 +++ sys/arch/amd64/conf/GENERIC 25 Aug 2018 18:39:09 - @@ -257,6 +257,8 @@ wsmouse* at ubcmtp? mux 0 uhidev*at uhub?# Human Interface Devices ums* at uhidev? # USB mouse wsmouse* at ums? mux 0 +umt* at uhidev? # Multitouch touchpad +wsmouse* at umt? mux 0 uts* at uhub?# USB touchscreen wsmouse* at uts? mux 0 uwacom*at uhidev? # USB Wacom tablet Index: share/man/man4/Makefile === RCS file: /cvs/src/share/man/man4/Makefile,v retrieving revision 1.690 diff -u -p -u -p -r1.690 Makefile --- share/man/man4/Makefile 19 Aug 2018 11:42:33 - 1.690 +++ share/man/man4/Makefile 25 Aug 2018 18:39:09 - @@ -75,8 +75,8 @@ MAN= aac.4 ac97.4 acphy.4 acrtc.4 \ uftdi.4 ugen.4 ugl.4 ugold.4 uguru.4 uhci.4 uhid.4 uhidev.4 uipaq.4 \ uk.4 ukbd.4 \ ukphy.4 ulpt.4 umass.4 umb.4 umbg.4 umcs.4 umct.4 umidi.4 umodem.4 \ - ums.4 umsm.4 unix.4 uonerng.4 uow.4 uoaklux.4 uoakrh.4 uoakv.4 upd.4 \ - upgt.4 upl.4 uplcom.4 ural.4 ure.4 url.4 urlphy.4 \ + ums.4 umsm.4 umt.4 unix.4 uonerng.4 uow.4 uoaklux.4 uoakrh.4 uoakv.4 \ + upd.4 upgt.4 upl.4 uplcom.4 ural.4 ure.4 url.4 urlphy.4 \ urndis.4 urng.4 urtw.4 urtwn.4 usb.4 uscom.4 uslcom.4 usps.4 \ uthum.4 uticom.4 utpms.4 utwitch.4 utrh.4 uts.4 utvfu.4 uvideo.4 \ uvisor.4 uvscom.4 uwacom.4 \ Index: share/man/man4/uhidev.4 === RCS file: /cvs/src/share/man/man4/uhidev.4,v retrieving revision 1.9 diff -u -p -u -p -r1.9 uhidev.4 --- share/man/man4/uhidev.4 12 Sep 2016 08:12:06 - 1.9 +++ share/man/man4/uhidev.4 25 Aug 2018 18:39:09 - @@ -42,6 +42,7 @@ .Cd "uhid*at uhidev?" .Cd "ukbd*at uhidev?" .Cd "ums* at uhidev?" +.Cd "umt* at uhidev?" .Cd "uoaklux* at uhidev?" .Cd "uoakrh* at uhidev?" .Cd "uoakv* at uhidev?" @@ -73,6 +74,7 @@ only dispatches data to them based on th .Xr uhid 4 , .Xr ukbd 4 , .Xr ums 4 , +.Xr umt 4 , .Xr uoaklux 4 , .Xr uoakrh 4 , .Xr uoakv 4 , Index: share/man/man4/umt.4 === RCS file: share/man/man4/umt.4 diff -N share/man/man4/umt.4 --- /dev/null 1 Jan 1970 00:00:00 - +++ share/man/man4/umt.425 Aug 2018 18:39:10 - @@ -0,0 +1,47 @@ +.\"$OpenBSD$ +.\" +.\" Copyright (c) 2016-2018 joshua stein +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate$ +.Dt UMT 4 +.Os +.Sh NAME +.Nm umt +.Nd USB HID multitouch touchpad support +.Sh SYNOPSIS +.Cd "umt* at uhidev?" +.Cd "wsmouse* at umt? mux 0" +.Sh DESCRIPTION +The +.Nm +driver provides support for USB HID touchpads conforming to the +Windows Precision Touchpad standard. +Access to these devices is through the +.Xr wscons 4 +driver. +.Sh SEE ALSO +.Xr uhidev 4 , +.Xr ums 4 , +.Xr wsmouse 4 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Ox 6.4 . +.Sh AUTHORS +The +.Nm +driver was written by +.An joshua stein Aq Mt j...@openbsd.org . Index: share/man/man4/usb.4 === RCS file: /cvs/src/share/man/man4/usb.4,v retrieving revision 1.188 diff -u -p -u -p -r1.188 usb.4 --- share/man/man4/usb.43 Aug 2018 01:50:14 - 1.188 +++ share/man/man4/usb.425 Aug 2018 18:39:10 - @@ -248,6 +248,8 @@ Base driver for all Human Interface Devi USB keyboards that follow the boot protocol .It Xr ums 4 USB HI
fix hid constant conversion
The HID code uses hid_feature, hid_input, and hid_output constants to refer to report types internally that then need to be converted to their bus-level counterparts before actually getting sent out (so hid_feature becomes UHID_FEATURE_REPORT for USB, I2C_HID_REPORT_TYPE_FEATURE for i2c). This conversion was hard-coded in ihidev when I wrote it, but ihidev_[gs]et_report should assume the type passed is already an i2c-level define, not a hid one. This is how uhidev does it. So add a conversion routine callback that any hidmt callers need to set so that hidmt can convert hid constants to the bus-level versions before then calling the get/set report functions. Also add a similar conversion function to uhidev for an upcoming driver. Index: dev/hid/hidmt.c === RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.7 diff -u -p -u -p -r1.7 hidmt.c --- dev/hid/hidmt.c 30 Jul 2018 15:56:30 - 1.7 +++ dev/hid/hidmt.c 25 Aug 2018 02:21:18 - @@ -126,7 +126,11 @@ hidmt_setup(struct device *self, struct capsize = hid_report_size(desc, dlen, hid_feature, mt->sc_rep_cap); rep = malloc(capsize, M_DEVBUF, M_NOWAIT | M_ZERO); - if (mt->hidev_get_report(mt->sc_device, hid_feature, mt->sc_rep_cap, + if (mt->hidev_report_type_conv == NULL) + panic("no report type conversion function"); + + if (mt->hidev_get_report(mt->sc_device, + mt->hidev_report_type_conv(hid_feature), mt->sc_rep_cap, rep, capsize)) { printf("\n%s: failed getting capability report\n", self->dv_xname); @@ -278,8 +282,12 @@ hidmt_detach(struct hidmt *mt, int flags int hidmt_set_input_mode(struct hidmt *mt, uint16_t mode) { - return mt->hidev_set_report(mt->sc_device, hid_feature, - mt->sc_rep_config, &mode, 2); + if (mt->hidev_report_type_conv == NULL) + panic("no report type conversion function"); + + return mt->hidev_set_report(mt->sc_device, + mt->hidev_report_type_conv(hid_feature), + mt->sc_rep_config, &mode, sizeof(mode)); } void Index: dev/hid/hidmtvar.h === RCS file: /cvs/src/sys/dev/hid/hidmtvar.h,v retrieving revision 1.5 diff -u -p -u -p -r1.5 hidmtvar.h --- dev/hid/hidmtvar.h 10 Oct 2017 20:31:50 - 1.5 +++ dev/hid/hidmtvar.h 25 Aug 2018 02:21:18 - @@ -39,6 +39,7 @@ struct hidmt { #define HIDMT_REVY 0x0001 /* Y-axis is reversed ("natural" scrolling) */ struct device *sc_device; + int (*hidev_report_type_conv)(int); int (*hidev_get_report)(struct device *, int, int, void *, int); int (*hidev_set_report)(struct device *, int, int, void *, Index: dev/i2c/ihidev.c === RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v retrieving revision 1.16 diff -u -p -u -p -r1.16 ihidev.c --- dev/i2c/ihidev.c12 Jan 2018 08:11:47 - 1.16 +++ dev/i2c/ihidev.c25 Aug 2018 02:21:18 - @@ -787,7 +787,6 @@ ihidev_get_report_desc(struct ihidev_sof *size = sc->sc_reportlen; } -/* convert hid_* constants used throughout HID code to i2c HID equivalents */ int ihidev_report_type_conv(int hid_type_id) { @@ -808,12 +807,8 @@ ihidev_get_report(struct device *dev, in { struct ihidev_softc *sc = (struct ihidev_softc *)dev; struct i2c_hid_report_request rreq; - int ctype; - if ((ctype = ihidev_report_type_conv(type)) < 0) - return (1); - - rreq.type = ctype; + rreq.type = type; rreq.id = id; rreq.data = data; rreq.len = len; @@ -831,12 +826,8 @@ ihidev_set_report(struct device *dev, in { struct ihidev_softc *sc = (struct ihidev_softc *)dev; struct i2c_hid_report_request rreq; - int ctype; - - if ((ctype = ihidev_report_type_conv(type)) < 0) - return (1); - rreq.type = ctype; + rreq.type = type; rreq.id = id; rreq.data = data; rreq.len = len; Index: dev/i2c/ihidev.h === RCS file: /cvs/src/sys/dev/i2c/ihidev.h,v retrieving revision 1.5 diff -u -p -u -p -r1.5 ihidev.h --- dev/i2c/ihidev.h29 Nov 2017 02:48:16 - 1.5 +++ dev/i2c/ihidev.h25 Aug 2018 02:21:18 - @@ -128,5 +128,6 @@ int ihidev_open(struct ihidev *); void ihidev_close(struct ihidev *); int ihidev_ioctl(struct ihidev *, u_long, caddr_t, int, struct proc *); +int ihidev_report_type_conv(int); int ihidev_set_report(struct device *, int, int, void *, int); int ihidev_get_report(struct device *, int, int, void *, int); Index: dev/i2c/imt.c === RCS file: /cvs/src/sys/dev/i2c/imt
ubcmtp: fix multi-finger on type4 devices, pass in proper pressure
Type 4 devices like the MacBookPro12,1 have extra padding in between each chunk of finger data that needs to be skipped, otherwise the offset will be wrong and each additional finger will read as static coordinates. This must have been overlooked when it was added to the driver in 2015 since the first finger of data always read properly. Also, we can now pass in the actual pressure data instead of having to use a constant value just to make the synaptics driver happy since we now have wstpad. The per-type min/max pressure values can also be passed in when calling wsmouse_configure. Tested on the 2015 MacBook Pro. Tests on other Apple devices would be appreciated. Index: sys/dev/usb/ubcmtp.c === RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v retrieving revision 1.18 diff -u -p -u -p -r1.18 ubcmtp.c --- sys/dev/usb/ubcmtp.c30 Jul 2018 15:56:30 - 1.18 +++ sys/dev/usb/ubcmtp.c16 Aug 2018 02:42:11 - @@ -118,6 +118,7 @@ struct ubcmtp_finger { #define UBCMTP_TYPE4_TPLEN UBCMTP_TYPE4_TPOFF + UBCMTP_ALL_FINGER_SIZE #define UBCMTP_TYPE4_TPIFACE 2 #define UBCMTP_TYPE4_BTOFF 31 +#define UBCMTP_TYPE4_FINGERPAD (1 * sizeof(uint16_t)) #define UBCMTP_FINGER_ORIENT 16384 #define UBCMTP_SN_PRESSURE 45 @@ -128,9 +129,6 @@ struct ubcmtp_finger { /* Identify clickpads in ubcmtp_configure. */ #define IS_CLICKPAD(ubcmtp_type) (ubcmtp_type != UBCMTP_TYPE1) -/* Use a constant, synaptics-compatible pressure value for now. */ -#define DEFAULT_PRESSURE 40 - struct ubcmtp_limit { int limit; int min; @@ -337,6 +335,7 @@ struct ubcmtp_softc { int sc_tp_epaddr; /* endpoint addr */ int tp_maxlen; /* max size of tp data */ int tp_offset; /* finger offset into data */ + int tp_fingerpad; /* padding between finger data */ uint8_t *tp_pkt; int bt_ifacenum;/* button interface number */ @@ -425,6 +424,7 @@ ubcmtp_attach(struct device *parent, str sc->sc_udev = uaa->device; sc->sc_status = 0; + sc->tp_fingerpad = 0; if ((udd = usbd_get_device_descriptor(dev)) == NULL) { printf("ubcmtp: failed getting device descriptor\n"); @@ -478,6 +478,7 @@ ubcmtp_attach(struct device *parent, str sc->tp_maxlen = UBCMTP_TYPE4_TPLEN; sc->tp_offset = UBCMTP_TYPE4_TPOFF; sc->tp_ifacenum = UBCMTP_TYPE4_TPIFACE; + sc->tp_fingerpad = UBCMTP_TYPE4_FINGERPAD; break; } @@ -520,6 +521,10 @@ int ubcmtp_configure(struct ubcmtp_softc *sc) { struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); + struct wsmouse_param params[] = { + { WSMOUSECFG_PRESSURE_LO, sc->dev_type->l_pressure.min }, + { WSMOUSECFG_PRESSURE_HI, sc->dev_type->l_pressure.max }, + }; hw->type = WSMOUSE_TYPE_TOUCHPAD; hw->hw_type = (IS_CLICKPAD(sc->dev_type->type) @@ -531,7 +536,7 @@ ubcmtp_configure(struct ubcmtp_softc *sc hw->mt_slots = UBCMTP_MAX_FINGERS; hw->flags = WSMOUSEHW_MT_TRACKING; - return wsmouse_configure(sc->sc_wsmousedev, NULL, 0); + return wsmouse_configure(sc->sc_wsmousedev, params, 0); } int @@ -793,9 +798,9 @@ void ubcmtp_tp_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct ubcmtp_softc *sc = priv; - struct ubcmtp_finger *pkt; + struct ubcmtp_finger *finger; u_int32_t pktlen; - int i, s, btn, contacts, fingers; + int off, s, btn, contacts = 0; if (usbd_is_dying(sc->sc_udev) || !(sc->sc_status & UBCMTP_ENABLED)) return; @@ -816,16 +821,19 @@ ubcmtp_tp_intr(struct usbd_xfer *xfer, v if (sc->tp_pkt == NULL || pktlen < sc->tp_offset) return; - pkt = (struct ubcmtp_finger *)(sc->tp_pkt + sc->tp_offset); - fingers = (pktlen - sc->tp_offset) / sizeof(struct ubcmtp_finger); - contacts = 0; - for (i = 0; i < fingers; i++) { - if ((int16_t)letoh16(pkt[i].touch_major) == 0) + for (off = sc->tp_offset; off < pktlen; + off += (sizeof(struct ubcmtp_finger) + sc->tp_fingerpad)) { + finger = (struct ubcmtp_finger *)(sc->tp_pkt + off); + + if ((int16_t)letoh16(finger->touch_major) == 0) continue; /* finger lifted */ - sc->frame[contacts].x = (int16_t)letoh16(pkt[i].abs_x); - sc->frame[contacts].y = (int16_t)letoh16(pkt[i].abs_y); - sc->frame[contacts].pressure = DEFAULT_PRESSURE; + + sc->frame[contacts].x = (int16_t)letoh16(finger->abs_x); + sc->frame[contacts].y = (int16_t)letoh16(finger->abs_y); + sc->frame[contacts].pressure = +
stop using WSMOUSE_TYPE_ELANTECH in other drivers (xenocara)
And here is the xenocara part. Index: xserver/config/wscons.c === RCS file: /cvs/xenocara/xserver/config/wscons.c,v retrieving revision 1.21 diff -u -p -u -p -r1.21 wscons.c --- xserver/config/wscons.c 8 Dec 2017 15:02:00 - 1.21 +++ xserver/config/wscons.c 27 Jul 2018 19:54:17 - @@ -239,6 +239,7 @@ wscons_add_pointers(void) case WSMOUSE_TYPE_ALPS: case WSMOUSE_TYPE_ELANTECH: case WSMOUSE_TYPE_SYNAP_SBTN: + case WSMOUSE_TYPE_TOUCHPAD: wscons_add_pointer(devnam, "ws", ATTR_TOUCHPAD); break;
stop using WSMOUSE_TYPE_ELANTECH in other drivers
Back when touchpad drivers were using the synaptics Xorg driver, they had to pretend to be Elantech devices in order to get particular packet processing. Since Ulf switched us to wstpad and xf86-input-ws a while ago, these drivers can stop claiming to be WSMOUSE_TYPE_ELANTECH devices and use a common WSMOUSE_TYPE_TOUCHPAD. This also makes the WSMOUSEIO_GTYPE ioctl in those drivers respond with whatever is stored in the softc to avoid repeating ourselves (or possibly responding incorrectly). There's also a corresponding xenocara diff coming after this. Index: sys/dev/hid/hidmt.c === RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.6 diff -u -p -u -p -r1.6 hidmt.c --- sys/dev/hid/hidmt.c 10 Oct 2017 20:31:50 - 1.6 +++ sys/dev/hid/hidmt.c 27 Jul 2018 19:53:59 - @@ -235,7 +235,7 @@ hidmt_configure(struct hidmt *mt) return; hw = wsmouse_get_hw(mt->sc_wsmousedev); - hw->type = WSMOUSE_TYPE_ELANTECH; /* see hidmt_ioctl */ + hw->type = WSMOUSE_TYPE_TOUCHPAD; hw->hw_type = (mt->sc_clickpad ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD); hw->x_min = mt->sc_minx; @@ -468,13 +468,11 @@ hidmt_ioctl(struct hidmt *mt, u_long cmd int wsmode; switch (cmd) { - case WSMOUSEIO_GTYPE: - /* -* So we can specify our own finger/w values to the -* xf86-input-synaptics driver like pms(4) -*/ - *(u_int *)data = WSMOUSE_TYPE_ELANTECH; + case WSMOUSEIO_GTYPE: { + struct wsmousehw *hw = wsmouse_get_hw(mt->sc_wsmousedev); + *(u_int *)data = hw->type; break; + } case WSMOUSEIO_GCALIBCOORDS: wsmc->minx = mt->sc_minx; Index: sys/dev/i2c/iatp.c === RCS file: /cvs/src/sys/dev/i2c/iatp.c,v retrieving revision 1.5 diff -u -p -u -p -r1.5 iatp.c --- sys/dev/i2c/iatp.c 22 Jun 2018 15:58:26 - 1.5 +++ sys/dev/i2c/iatp.c 27 Jul 2018 19:53:59 - @@ -325,7 +325,7 @@ iatp_configure(struct iatp_softc *sc) hw = wsmouse_get_hw(sc->sc_wsmousedev); if (sc->sc_touchpad) { - hw->type = WSMOUSE_TYPE_SYNAPTICS; + hw->type = WSMOUSE_TYPE_TOUCHPAD; hw->hw_type = WSMOUSEHW_CLICKPAD; } else { hw->type = WSMOUSE_TYPE_TPANEL; @@ -415,12 +415,11 @@ iatp_ioctl(void *v, u_long cmd, caddr_t wsmc->resy = sc->sc_tsscale.resy; break; - case WSMOUSEIO_GTYPE: - if (sc->sc_touchpad) - *(u_int *)data = WSMOUSE_TYPE_SYNAPTICS; - else - *(u_int *)data = WSMOUSE_TYPE_TPANEL; + case WSMOUSEIO_GTYPE: { + struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); + *(u_int *)data = hw->type; break; + } case WSMOUSEIO_SETMODE: if (!sc->sc_touchpad) Index: sys/dev/usb/ubcmtp.c === RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v retrieving revision 1.17 diff -u -p -u -p -r1.17 ubcmtp.c --- sys/dev/usb/ubcmtp.c6 Jun 2017 21:53:07 - 1.17 +++ sys/dev/usb/ubcmtp.c27 Jul 2018 19:53:59 - @@ -521,7 +521,7 @@ ubcmtp_configure(struct ubcmtp_softc *sc { struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); - hw->type = WSMOUSE_TYPE_ELANTECH; /* see ubcmtp_ioctl */ + hw->type = WSMOUSE_TYPE_TOUCHPAD; hw->hw_type = (IS_CLICKPAD(sc->dev_type->type) ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD); hw->x_min = sc->dev_type->l_x.min; @@ -601,11 +601,11 @@ ubcmtp_ioctl(void *v, unsigned long cmd, cmd); switch (cmd) { - case WSMOUSEIO_GTYPE: - /* so we can specify our own finger/w values to the -* xf86-input-synaptics driver like pms(4) */ - *(u_int *)data = WSMOUSE_TYPE_ELANTECH; + case WSMOUSEIO_GTYPE: { + struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); + *(u_int *)data = hw->type; break; + } case WSMOUSEIO_GCALIBCOORDS: wsmc->minx = sc->dev_type->l_x.min; Index: sys/dev/wscons/wsconsio.h === RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v retrieving revision 1.88 diff -u -p -u -p -r1.88 wsconsio.h --- sys/dev/wscons/wsconsio.h 7 May 2018 21:58:42 - 1.88 +++ sys/dev/wscons/wsconsio.h 27 Jul 2018 19:53:59 - @@ -238,6 +238,7 @@ struct wskbd_encoding_data { #defineWSMOUSE_TYPE_SGI17 /* SGI serial mouse */ #defineWSMOUSE_TYPE_ELANTECH 18 /* Elantech touchpad */ #define
Re: inteldrm: always use probed screen size for fb
On Fri, 27 Jul 2018 at 19:44:28 +0200, Mark Kettenis wrote: > > Date: Thu, 26 Jul 2018 17:56:03 -0500 > > From: joshua stein > > > > On Thu, 26 Jul 2018 at 22:26:51 +0200, Mark Kettenis wrote: > > > I'm hesitant to change this code. How does Linux behave on tese > > > machines? Does it use the invisible part of the framebuffer? Or have > > > they done away with actually using the kernel framebuffer completely > > > like some developers threatened a couple of years ago... > > > > I booted a Linux USB drive and it just shows a purple/black screen > > for a few seconds while the kernel loads until some text flashes for > > half a second (systemd?) and then X loads. When I switch back to > > the console, it doesn't draw off the screen. I have no idea what > > it's doing under the hood to figure out the resolution for the > > console. > > All the information about the size of the connected displays is there. > But it is unclear to me how that information is propagated to the > Linux kernel framebuffer code. > > Anyway, here is an alternative diff. This keeps the BIOS framebuffer > but only uses the area that corresponds to the size we want. Keeping > the BIOS framebuffer has some benefits. On many systems that > framebuffer lives in "stolen" memory that we can't really use for any > other purpose because the BIOS owns it. Also keeping the BIOS > framebuffer would avoid a mode switch (at least in theory) and speed > up the boot processes. Works For Me (tm) > Index: dev/pci/drm/i915/intel_fbdev.c > === > RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_fbdev.c,v > retrieving revision 1.3 > diff -u -p -r1.3 intel_fbdev.c > --- dev/pci/drm/i915/intel_fbdev.c1 Jul 2017 16:14:10 - 1.3 > +++ dev/pci/drm/i915/intel_fbdev.c27 Jul 2018 17:26:33 - > @@ -220,8 +220,10 @@ static int intelfb_create(struct drm_fb_ > } else { > DRM_DEBUG_KMS("re-using BIOS fb\n"); > prealloc = true; > +#ifdef __linux__ > sizes->fb_width = intel_fb->base.width; > sizes->fb_height = intel_fb->base.height; > +#endif > } > > obj = intel_fb->obj; >
Re: inteldrm: always use probed screen size for fb
On Thu, 26 Jul 2018 at 22:26:51 +0200, Mark Kettenis wrote: > I'm hesitant to change this code. How does Linux behave on tese > machines? Does it use the invisible part of the framebuffer? Or have > they done away with actually using the kernel framebuffer completely > like some developers threatened a couple of years ago... I booted a Linux USB drive and it just shows a purple/black screen for a few seconds while the kernel loads until some text flashes for half a second (systemd?) and then X loads. When I switch back to the console, it doesn't draw off the screen. I have no idea what it's doing under the hood to figure out the resolution for the console. (I'd make a joke about Linux developers hiding all of that ugly kernel text output from users, but ironically the OpenBSD kernel wastes about 5-8 seconds during boot just printing kernel text through rasops.) > Do you have a (larger) monitor connected to your laptops when this happens? No, nothing connected. BTW this diff is in snaps.
inteldrm: always use probed screen size for fb
On the 2015 MacBook Pro and the 12" MacBook, the firmware reports a framebuffer size of 2880x1800 but the screens are 2560x1600 and 2304x1440. Our console ends up drawing text off screen and the latest few lines can't be read. Once X loads, it probes the outputs again and uses the proper resolution. For the console, the outputs are already being probed but the BIOS resolution is only discarded if it's too small. I'd like to change it to discard it if it's too large as well, so it uses the actual resolution probed. On a machine like a server where inteldrm loads but has nothing connected, intel_fb is null, so this code doesn't run. Index: sys/dev/pci/drm/i915/intel_fbdev.c === RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_fbdev.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 intel_fbdev.c --- sys/dev/pci/drm/i915/intel_fbdev.c 1 Jul 2017 16:14:10 - 1.3 +++ sys/dev/pci/drm/i915/intel_fbdev.c 23 Jul 2018 17:58:03 - @@ -202,10 +202,9 @@ static int intelfb_create(struct drm_fb_ mutex_lock(&dev->struct_mutex); if (intel_fb && - (sizes->fb_width > intel_fb->base.width || -sizes->fb_height > intel_fb->base.height)) { - DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d)," - " releasing it\n", + (sizes->fb_width != intel_fb->base.width || +sizes->fb_height != intel_fb->base.height)) { + DRM_DEBUG_KMS("BIOS fb %dx%d != %dx%d, releasing it\n", intel_fb->base.width, intel_fb->base.height, sizes->fb_width, sizes->fb_height); drm_framebuffer_unreference(&intel_fb->base);
Re: realpath(3) on a dangling symlink
On Wed, 27 Jun 2018 at 21:35:31 -0500, joshua stein wrote: > symlink("/tmp/link", "/tmp/nonexistent"); Oops, I changed this test code at the last second. The proper test code which incorrectly prints on OpenBSD: resolved realpath of /tmp/nonexistent (returned /tmp/nonexistent), errno is 2 #include #include #include #include #include #include int main() { char resolved[1024]; char *ret; unlink("/tmp/link"); unlink("/tmp/nonexistent"); symlink("/tmp/nonexistent", "/tmp/link"); ret = realpath("/tmp/link", resolved); if (ret == NULL) printf("realpath failed: %s\n", strerror(errno)); else printf("resolved realpath of %s (returned %s), errno is %d\n", resolved, ret, errno); return (0); }
realpath(3) on a dangling symlink
realpath(3) on a symlink that points to a non-existent path returns that path (but also sets errno), rather than returning NULL and setting errno. This is inconsistent with at least Linux, FreeBSD, and macOS. #include #include #include #include #include #include int main() { char resolved[1024]; char *ret; unlink("/tmp/link"); unlink("/tmp/nonexistent"); symlink("/tmp/link", "/tmp/nonexistent"); ret = realpath("/tmp/link", resolved); if (ret == NULL) printf("realpath failed: %s\n", strerror(errno)); else printf("resolved realpath of %s (returned %s), errno is %d\n", resolved, ret, errno); return (0); } Should print: realpath failed: No such file or directory But prints: resolved realpath of /tmp/link (returned /tmp/link), errno is 2 This makes it fall through to the error case (in case any memory needs to be freed) and return NULL. Index: lib/libc/stdlib/realpath.c === RCS file: /cvs/src/lib/libc/stdlib/realpath.c,v retrieving revision 1.22 diff -u -p -u -p -r1.22 realpath.c --- lib/libc/stdlib/realpath.c 24 Dec 2017 01:50:50 - 1.22 +++ lib/libc/stdlib/realpath.c 28 Jun 2018 02:24:37 - @@ -163,10 +163,8 @@ realpath(const char *path, char *resolve /* not a symlink, continue to next component */ continue; case ENOENT: - if (p == NULL) { + if (p == NULL) errno = serrno; - return (resolved); - } /* FALLTHROUGH */ default: goto err;
Re: rasops: implement scrollback for inteldrm and efifb
On Tue, 17 Apr 2018 at 07:52:28 +0200, Mark Kettenis wrote: > > Date: Mon, 16 Apr 2018 10:45:52 -0500 > > From: joshua stein > > Does this do the right thing for early consoles? The initial > efifb_bs[] doesn't have space for the scrollback. At the point where > the scrollback code gets code, we've replaced that with a malloc'ed > buffer? Here is a new version that puts the scrollback count into each rasops_screen in case it changes later, which allows it to cope with the count being 0 if no scrollback has been allocated. Though the scrollback callback won't be called until wsdisplay formally attaches later after each rasops_screen is allocated anyway. Index: arch/amd64/amd64/efifb.c === RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v retrieving revision 1.15 diff -u -p -u -p -r1.15 efifb.c --- arch/amd64/amd64/efifb.c25 Apr 2018 00:46:28 - 1.15 +++ arch/amd64/amd64/efifb.c27 Apr 2018 14:27:22 - @@ -101,6 +101,7 @@ int efifb_show_screen(void *, void *, i void *); int efifb_list_font(void *, struct wsdisplay_font *); int efifb_load_font(void *, void *, struct wsdisplay_font *); +voidefifb_scrollback(void *, void *, int lines); voidefifb_efiinfo_init(struct efifb *); voidefifb_cnattach_common(void); @@ -133,7 +134,8 @@ struct wsdisplay_accessops efifb_accesso .free_screen = efifb_free_screen, .show_screen = efifb_show_screen, .load_font = efifb_load_font, - .list_font = efifb_list_font + .list_font = efifb_list_font, + .scrollback = efifb_scrollback, }; struct cfdriver efifb_cd = { @@ -397,6 +399,15 @@ efifb_list_font(void *v, struct wsdispla struct rasops_info *ri = &sc->sc_fb->rinfo; return (rasops_list_font(ri, font)); +} + +void +efifb_scrollback(void *v, void *cookie, int lines) +{ + struct efifb_softc *sc = v; + struct rasops_info *ri = &sc->sc_fb->rinfo; + + rasops_scrollback(ri, cookie, lines); } int Index: dev/rasops/rasops.c === RCS file: /cvs/src/sys/dev/rasops/rasops.c,v retrieving revision 1.52 diff -u -p -u -p -r1.52 rasops.c --- dev/rasops/rasops.c 20 Apr 2018 16:09:37 - 1.52 +++ dev/rasops/rasops.c 27 Apr 2018 14:27:23 - @@ -1373,6 +1373,11 @@ struct rasops_screen { int rs_visible; int rs_crow; int rs_ccol; + + int rs_sbscreens; +#define RS_SCROLLBACK_SCREENS 5 + int rs_dispoffset; /* rs_bs index, start of our actual screen */ + int rs_visibleoffset; /* rs_bs index, current scrollback screen */ }; int @@ -1387,13 +1392,16 @@ rasops_alloc_screen(void *v, void **cook if (scr == NULL) return (ENOMEM); - scr->rs_bs = mallocarray(ri->ri_rows, + scr->rs_sbscreens = RS_SCROLLBACK_SCREENS; + scr->rs_bs = mallocarray(ri->ri_rows * (scr->rs_sbscreens + 1), ri->ri_cols * sizeof(struct wsdisplay_charcell), M_DEVBUF, M_NOWAIT); if (scr->rs_bs == NULL) { free(scr, M_DEVBUF, sizeof(*scr)); return (ENOMEM); } + scr->rs_visibleoffset = scr->rs_dispoffset = ri->ri_rows * + scr->rs_sbscreens * ri->ri_cols; *cookiep = scr; *curxp = 0; @@ -1405,13 +1413,19 @@ rasops_alloc_screen(void *v, void **cook scr->rs_crow = -1; scr->rs_ccol = -1; + for (i = 0; i < scr->rs_dispoffset; i++) { + scr->rs_bs[i].uc = ' '; + scr->rs_bs[i].attr = *attrp; + } + if (ri->ri_bs && scr->rs_visible) { - memcpy(scr->rs_bs, ri->ri_bs, ri->ri_rows * ri->ri_cols * + memcpy(scr->rs_bs + scr->rs_dispoffset, ri->ri_bs, + ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell)); } else { for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { - scr->rs_bs[i].uc = ' '; - scr->rs_bs[i].attr = *attrp; + scr->rs_bs[scr->rs_dispoffset + i].uc = ' '; + scr->rs_bs[scr->rs_dispoffset + i].attr = *attrp; } } @@ -1431,7 +1445,8 @@ rasops_free_screen(void *v, void *cookie ri->ri_nscreens--; free(scr->rs_bs, M_DEVBUF, - ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell)); + ri->ri_rows * (scr->rs_sbscreens + 1) * ri->ri_cols * + sizeof(struct wsdisplay_charcell)); free(scr, M_DEVBUF, sizeof(*scr)); } @@ -1467,9 +1482,11 @@ rasops_doswitch(void *v) ri->ri_eraserows
rasops: implement scrollback for inteldrm and efifb
Index: arch/amd64/amd64/efifb.c === RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v retrieving revision 1.12 diff -u -p -u -p -r1.12 efifb.c --- arch/amd64/amd64/efifb.c28 Oct 2017 01:48:03 - 1.12 +++ arch/amd64/amd64/efifb.c16 Apr 2018 15:40:22 - @@ -101,6 +101,7 @@ int efifb_show_screen(void *, void *, i void *); int efifb_list_font(void *, struct wsdisplay_font *); int efifb_load_font(void *, void *, struct wsdisplay_font *); +voidefifb_scrollback(void *, void *, int lines); voidefifb_efiinfo_init(struct efifb *); voidefifb_cnattach_common(void); @@ -133,7 +134,8 @@ struct wsdisplay_accessops efifb_accesso .free_screen = efifb_free_screen, .show_screen = efifb_show_screen, .load_font = efifb_load_font, - .list_font = efifb_list_font + .list_font = efifb_list_font, + .scrollback = efifb_scrollback, }; struct cfdriver efifb_cd = { @@ -397,6 +399,15 @@ efifb_list_font(void *v, struct wsdispla struct rasops_info *ri = &sc->sc_fb->rinfo; return (rasops_list_font(ri, font)); +} + +void +efifb_scrollback(void *v, void *cookie, int lines) +{ + struct efifb_softc *sc = v; + struct rasops_info *ri = &sc->sc_fb->rinfo; + + rasops_scrollback(ri, cookie, lines); } int Index: dev/rasops/rasops.c === RCS file: /cvs/src/sys/dev/rasops/rasops.c,v retrieving revision 1.50 diff -u -p -u -p -r1.50 rasops.c --- dev/rasops/rasops.c 23 Jan 2018 10:10:32 - 1.50 +++ dev/rasops/rasops.c 16 Apr 2018 15:40:22 - @@ -1373,8 +1373,13 @@ struct rasops_screen { int rs_visible; int rs_crow; int rs_ccol; + + int rs_dispoffset; /* rs_bs index, start of our actual screen */ + int rs_visibleoffset; /* rs_bs index, current scrollback screen */ }; +#define RS_SCROLLBACK_SCREENS 5 + int rasops_alloc_screen(void *v, void **cookiep, int *curxp, int *curyp, long *attrp) @@ -1387,13 +1392,15 @@ rasops_alloc_screen(void *v, void **cook if (scr == NULL) return (ENOMEM); - scr->rs_bs = mallocarray(ri->ri_rows, + scr->rs_bs = mallocarray(ri->ri_rows * RS_SCROLLBACK_SCREENS, ri->ri_cols * sizeof(struct wsdisplay_charcell), M_DEVBUF, M_NOWAIT); if (scr->rs_bs == NULL) { free(scr, M_DEVBUF, sizeof(*scr)); return (ENOMEM); } + scr->rs_visibleoffset = scr->rs_dispoffset = ri->ri_rows * + (RS_SCROLLBACK_SCREENS - 1) * ri->ri_cols; *cookiep = scr; *curxp = 0; @@ -1405,13 +1412,19 @@ rasops_alloc_screen(void *v, void **cook scr->rs_crow = -1; scr->rs_ccol = -1; + for (i = 0; i < scr->rs_dispoffset; i++) { + scr->rs_bs[i].uc = ' '; + scr->rs_bs[i].attr = *attrp; + } + if (ri->ri_bs && scr->rs_visible) { - memcpy(scr->rs_bs, ri->ri_bs, ri->ri_rows * ri->ri_cols * + memcpy(scr->rs_bs + scr->rs_dispoffset, ri->ri_bs, + ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell)); } else { for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) { - scr->rs_bs[i].uc = ' '; - scr->rs_bs[i].attr = *attrp; + scr->rs_bs[scr->rs_dispoffset + i].uc = ' '; + scr->rs_bs[scr->rs_dispoffset + i].attr = *attrp; } } @@ -1431,7 +1444,8 @@ rasops_free_screen(void *v, void *cookie ri->ri_nscreens--; free(scr->rs_bs, M_DEVBUF, - ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell)); + ri->ri_rows * RS_SCROLLBACK_SCREENS * ri->ri_cols * + sizeof(struct wsdisplay_charcell)); free(scr, M_DEVBUF, sizeof(*scr)); } @@ -1467,9 +1481,11 @@ rasops_doswitch(void *v) ri->ri_eraserows(ri, 0, ri->ri_rows, attr); ri->ri_active = scr; ri->ri_active->rs_visible = 1; + ri->ri_active->rs_visibleoffset = ri->ri_active->rs_dispoffset; for (row = 0; row < ri->ri_rows; row++) { for (col = 0; col < ri->ri_cols; col++) { - int off = row * scr->rs_ri->ri_cols + col; + int off = row * scr->rs_ri->ri_cols + col + + scr->rs_visibleoffset; ri->ri_putchar(ri, row, col, scr->rs_bs[off].uc, scr->rs_bs[off].attr); @@ -1491,7 +1507,7 @@ rasops_getchar(void *v, int row, int col if (scr == NULL || scr->rs_bs == NULL) return (1); - *cell = scr->rs_bs[row * ri->ri_cols + col]; + *cell = scr->rs_bs[row * ri->ri_cols + col + scr->rs_dispoffset]; return (0); } @@ -1521,7 +1537,10 @
sysctl(8): add -F option to print temps in freedom units
Index: sbin/sysctl/sysctl.8 === RCS file: /cvs/src/sbin/sysctl/sysctl.8,v retrieving revision 1.214 diff -u -p -u -p -r1.214 sysctl.8 --- sbin/sysctl/sysctl.816 Feb 2018 07:27:07 - 1.214 +++ sbin/sysctl/sysctl.819 Feb 2018 17:10:19 - @@ -68,6 +68,8 @@ flag; for the table values, the name of List all the currently available string or integer values. This is the default, if no parameters are given to .Nm . +.It Fl F +Print temperature fields in Fahrenheit rather than Celsius. .It Fl n Suppress printing of the field name, only output the field value. Useful for setting shell variables. Index: sbin/sysctl/sysctl.c === RCS file: /cvs/src/sbin/sysctl/sysctl.c,v retrieving revision 1.230 diff -u -p -u -p -r1.230 sysctl.c --- sbin/sysctl/sysctl.c16 Feb 2018 07:27:07 - 1.230 +++ sbin/sysctl/sysctl.c19 Feb 2018 17:10:19 - @@ -158,7 +158,7 @@ struct list secondlevel[] = { { 0, 0 }, /* CTL_VFS */ }; -intAflag, aflag, nflag, qflag; +intAflag, aflag, Fflag, nflag, qflag; /* * Variables requiring special processing. @@ -221,7 +221,7 @@ main(int argc, char *argv[]) { int ch, lvl1; - while ((ch = getopt(argc, argv, "Aanqw")) != -1) { + while ((ch = getopt(argc, argv, "AaFnqw")) != -1) { switch (ch) { case 'A': @@ -232,6 +232,10 @@ main(int argc, char *argv[]) aflag = 1; break; + case 'F': + Fflag = 1; + break; + case 'n': nflag = 1; break; @@ -2561,8 +2565,12 @@ print_sensor(struct sensor *s) else { switch (s->type) { case SENSOR_TEMP: - printf("%.2f degC", - (s->value - 27315) / 100.0); + if (Fflag) + printf("%.2f degF", + (s->value * 1.8 - 45967) / 100.0); + else + printf("%.2f degC", + (s->value - 27315) / 100.0); break; case SENSOR_FANRPM: printf("%lld RPM", s->value);
pckbd: go back to using table 2 by default
In 2007 I changed this code to use table 3 by default, falling back on table 2 (the previous default) or 1. This was done just to make the keyboard on the OQO model 01 work, and these devices are long gone. 10 years later, some newer Lenovo machines seem to have trouble trying this mode which can occasionally leave the keyboard in a state where it generates bogus keys when typing. It also causes a long delay when booting because the table changes have to timeout: pckbd: trying table 3 pckbc_cmd: lost 0xee pckbc_cmd: timeout pckbd: table set of 3 failed pckbd: trying table 2 pckbc_cmd: lost 0xee pckbc_cmd: timeout pckbd: table set of 2 failed pckbd: trying table 1 pckbc_cmd: lost 0xee pckbc_cmd: timeout pckbd: table set of 1 failed pckbd: settling on table 1 This patch reverts back to using table 2 by default and if it says it was already in table 2, leaves it alone rather than forcibly changing to that mode again, which is how Linux behaves. Index: sys/dev/pckbc/pckbd.c === RCS file: /cvs/src/sys/dev/pckbc/pckbd.c,v retrieving revision 1.43 diff -u -p -u -p -r1.43 pckbd.c --- sys/dev/pckbc/pckbd.c 14 Apr 2016 07:06:03 - 1.43 +++ sys/dev/pckbc/pckbd.c 2 Jan 2018 15:21:05 - @@ -214,8 +214,7 @@ int pckbd_set_xtscancode(pckbc_tag_t kbctag, pckbc_slot_t kbcslot, struct pckbd_internal *id) { - /* default to have the 8042 translate the keyboard with table 3. */ - int table = 3; + int table; if (pckbc_xt_translation(kbctag)) { #ifdef DEBUG @@ -234,12 +233,21 @@ pckbd_set_xtscancode(pckbc_tag_t kbctag, if (id != NULL) id->t_translating = 0; } else { - if (id != NULL) + if (id != NULL) { id->t_translating = 1; + if (id->t_table == 0) { + /* +* Don't bother explicitly setting into set 2, +* it's the default. +*/ + id->t_table = 2; + return (0); + } + } } /* keep falling back until we hit a table that looks usable. */ - for (; table >= 1; table--) { + for (table = 3; table >= 1; table--) { u_char cmd[2]; #ifdef DEBUG printf("pckbd: trying table %d\n", table);
Re: ihidev(4) polling
On Thu, 16 Nov 2017 at 13:42:03 -0500, James Turner wrote: So I have to ask since when I hit you up on icb the above terms where all mentioned. With this diff and what you just committed to src add touchpad support to the Xiaomi Mi Air 12.5"? The Xiaomi Mi Air needs a Sunrise Point GPIO driver to do interrupts for the touchpad, so this workaround should help there too but the proper fix for that machine is to write a new driver.
ihidev(4) polling
Now that the dwiic(4) PCI support is in, this implements polling mode for ihidev to work around the problem of ioapic interrupts not arriving for them after setup. I've spent far too much time trying to debug that problem (including much of my time at t2k17), so I made this as a workaround until someone else fixes that issue. The new PCI attachment of dwiic sets sc_poll_ihidev, which dwiic_acpi_found_ihidev() checks for and does not set ia_intr, and this diff implements the other half which sets up a polling mode in response to that. It does slow polling by default to conserve power, and once movement is detected on a device under ihidev (like imt(4)), it starts polling quickly for a while. It's not perfect but it's enough to make the touchpad work on these machines and will hopefully be a temporary fix. Index: sys/dev/i2c/ihidev.c === RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v retrieving revision 1.13 diff -u -p -u -p -r1.13 ihidev.c --- sys/dev/i2c/ihidev.c8 Apr 2017 02:57:23 - 1.13 +++ sys/dev/i2c/ihidev.c16 Nov 2017 18:18:33 - @@ -38,6 +38,9 @@ #define DPRINTF(x) #endif +#define SLOW_POLL_MS 200 +#define FAST_POLL_MS 10 + /* 7.2 */ enum { I2C_HID_CMD_DESCR = 0x0, @@ -70,6 +73,8 @@ int ihidev_maxrepid(void *buf, int len); intihidev_print(void *aux, const char *pnp); intihidev_submatch(struct device *parent, void *cf, void *aux); +extern int hz; + struct cfattach ihidev_ca = { sizeof(struct ihidev_softc), ihidev_match, @@ -108,15 +113,27 @@ ihidev_attach(struct device *parent, str sc->sc_addr = ia->ia_addr; sc->sc_hid_desc_addr = ia->ia_size; - if (ia->ia_intr) - printf(" %s", iic_intr_string(sc->sc_tag, ia->ia_intr)); - if (ihidev_hid_command(sc, I2C_HID_CMD_DESCR, NULL) || ihidev_hid_desc_parse(sc)) { printf(", failed fetching initial HID descriptor\n"); return; } + if (ia->ia_intr) { + printf(" %s", iic_intr_string(sc->sc_tag, ia->ia_intr)); + + sc->sc_ih = iic_intr_establish(sc->sc_tag, ia->ia_intr, + IPL_TTY, ihidev_intr, sc, sc->sc_dev.dv_xname); + if (sc->sc_ih == NULL) + printf(", can't establish interrupt"); + } + + if (sc->sc_ih == NULL) { + printf(" (polling)"); + sc->sc_poll = 1; + sc->sc_fastpoll = 1; + } + printf(", vendor 0x%x product 0x%x, %s\n", letoh16(sc->hid_desc.wVendorID), letoh16(sc->hid_desc.wProductID), (char *)ia->ia_cookie); @@ -148,21 +165,12 @@ ihidev_attach(struct device *parent, str if (isize > sc->sc_isize) sc->sc_isize = isize; - DPRINTF(("%s: repid %d size %d\n", sc->sc_dev.dv_xname, repid, - repsz)); + if (repsz != 0) + DPRINTF(("%s: repid %d size %d\n", sc->sc_dev.dv_xname, + repid, repsz)); } sc->sc_ibuf = malloc(sc->sc_isize, M_DEVBUF, M_NOWAIT | M_ZERO); - /* register interrupt with system */ - if (ia->ia_intr) { - sc->sc_ih = iic_intr_establish(sc->sc_tag, ia->ia_intr, - IPL_TTY, ihidev_intr, sc, sc->sc_dev.dv_xname); - if (sc->sc_ih == NULL) { - printf(", can't establish interrupt\n"); - return; - } - } - iha.iaa = ia; iha.parent = sc; @@ -219,6 +227,20 @@ ihidev_detach(struct device *self, int f return (0); } +void +ihidev_sleep(struct ihidev_softc *sc, int ms) +{ + int to = ms * hz / 1000; + + if (cold) + delay(ms * 1000); + else { + if (to <= 0) + to = 1; + tsleep(&sc, PWAIT, "ihidev", to); + } +} + int ihidev_hid_command(struct ihidev_softc *sc, int hidcmd, void *arg) { @@ -363,7 +385,7 @@ ihidev_hid_command(struct ihidev_softc * I2C_HID_CMD_SET_REPORT, 0, 0, 0, 0, 0, 0, }; - int cmdlen = 10; + int cmdlen = sizeof(cmd); int report_id = rreq->id; int report_len = 2 + (report_id ? 1 : 0) + rreq->len; int dataoff; @@ -377,7 +399,7 @@ ihidev_hid_command(struct ihidev_softc * DPRINTF(("\n")); /* -* 7.2.2.4 - "The protocol is optimized for Report < 15. If a +* 7.2.3.4 - "The protocol is optimized for Report < 15. If a * report ID >= 15 is necessary, then the Report ID in the Low * Byte must be set to and a Third Byte is appended to the * protocol. This Third Byte contains the entire/
Re: dwiic: add pci attachment
Here is a new version of the dwiic patch that restores the acpi_attach_deps call, confirmed working by Cesare Gargano. Any other testers? Index: sys/conf/files === RCS file: /cvs/src/sys/conf/files,v retrieving revision 1.654 diff -u -p -u -p -r1.654 files --- sys/conf/files 3 Nov 2017 13:01:20 - 1.654 +++ sys/conf/files 10 Nov 2017 15:56:34 - @@ -524,6 +524,10 @@ file dev/spdmem.cspdmem device oaic: scsi filedev/ic/aic6250.coaic +# Synopsys DesignWare I2C controller +device dwiic: i2cbus +file dev/ic/dwiic.c dwiic + # legitimate pseudo-devices pseudo-device vnd: disk pseudo-device rd: disk Index: sys/dev/pci/dwiic_pci.c === RCS file: sys/dev/pci/dwiic_pci.c diff -N sys/dev/pci/dwiic_pci.c --- /dev/null 1 Jan 1970 00:00:00 - +++ sys/dev/pci/dwiic_pci.c 10 Nov 2017 15:56:34 - @@ -0,0 +1,204 @@ +/* $OpenBSD$ */ +/* + * Synopsys DesignWare I2C controller + * PCI attachment + * + * Copyright (c) 2015-2017 joshua stein + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* 13.3: I2C Additional Registers Summary */ +#define LPSS_RESETS0x204 +#define LPSS_RESETS_I2C (1 << 0) | (1 << 1) +#define LPSS_RESETS_IDMA (1 << 2) +#define LPSS_ACTIVELTR 0x210 +#define LPSS_IDLELTR 0x214 +#define LPSS_CAPS 0x2fc +#define LPSS_CAPS_NO_IDMA (1 << 8) +#define LPSS_CAPS_TYPE_SHIFT 4 +#define LPSS_CAPS_TYPE_MASK (0xf << LPSS_CAPS_TYPE_SHIFT) + +intdwiic_pci_match(struct device *, void *, void *); +void dwiic_pci_attach(struct device *, struct device *, void *); +intdwiic_pci_activate(struct device *, int); +void dwiic_pci_bus_scan(struct device *, + struct i2cbus_attach_args *, void *); + +#include "acpi.h" +#if NACPI > 0 +struct aml_node *acpi_pci_match(struct device *dev, struct pci_attach_args *pa); +#endif + +struct cfattach dwiic_pci_ca = { + sizeof(struct dwiic_softc), + dwiic_pci_match, + dwiic_pci_attach, + NULL, + dwiic_pci_activate, +}; + +const struct pci_matchid dwiic_pci_ids[] = { + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_I2C_1 }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_I2C_2 }, +}; + +int +dwiic_pci_match(struct device *parent, void *match, void *aux) +{ + return (pci_matchbyid(aux, dwiic_pci_ids, nitems(dwiic_pci_ids))); +} + +void +dwiic_pci_attach(struct device *parent, struct device *self, void *aux) +{ + struct dwiic_softc *sc = (struct dwiic_softc *)self; + struct pci_attach_args *pa = aux; + bus_size_t iosize; + pci_intr_handle_t ih; + const char *intrstr = NULL; + uint8_t type; + + memcpy(&sc->sc_paa, pa, sizeof(sc->sc_paa)); + + pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); + + if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT, 0, + &sc->sc_iot, &sc->sc_ioh, NULL, &iosize, 0)) { + printf(": can't map mem space\n"); + return; + } + + sc->sc_caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPSS_CAPS); + type = sc->sc_caps & LPSS_CAPS_TYPE_MASK; + type >>= LPSS_CAPS_TYPE_SHIFT; + if (type != 0) { + printf(": type %d not supported\n", type); + return; + } + + /* un-reset - page 958 */ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS, + (LPSS_RESETS_I2C | LPSS_RESETS_IDMA)); + + /* fetch timing parameters */ + sc->ss_hcnt = dwiic_read(sc, DW_IC_SS_SCL_HCNT); + sc->ss_lcnt = dwiic_read(sc, DW_IC_SS_SCL_LCNT); + sc->fs_hcnt = dwiic_read(sc, DW_IC_FS_SCL_HCNT); + sc->fs_lcnt = dwiic_read(sc, DW_IC_FS_SCL_LCNT); + sc->sda_hold_time = dwiic_read(sc, DW_IC_SDA_HOLD); + + if (dwiic_init(sc))
Re: dwiic: add pci attachment
On Thu, 09 Nov 2017 at 10:14:16 +0100, Remi Locherer wrote: On Fri, Nov 03, 2017 at 12:01:15PM -0500, joshua stein wrote: Intel 100 Series laptops have the DesignWare I2C controller attaching via PCI instead of ACPI, so move the guts of dwiic(4) into ic/ and add dwiic_acpi and dwiic_pci files. Unfortunately the PCI attachment still needs to reach into ACPI to discover client devices. There is still an issue with interrupt setup on these machines (unrelated to dwiic as far as I can tell), where ioapic interrupts registered for client devices like ihidev never fire, but those for dwiic (via PCI) do. This diff sets a flag for PCI-attached dwiic devices so that ihidev can do polling for client devices, which will come in a separate diff. I need some tests on machines where dwiic/ihidev attaches over ACPI. With your patch dwiic and also imt do attach. dwiic0 at pci0 dev 21 function 0 "Intel 100 Series I2C" rev 0x21: apic 2 int 16 iic0 at dwiic0 dwiic1 at pci0 dev 21 function 1 "Intel 100 Series I2C" rev 0x21: apic 2 int 17 iic1 at dwiic1 ihidev0 at iic1 addr 0x15, vendor 0x4f3 product 0x3035, ELAN1301 ihidev0: 11 report ids imt0 at ihidev0: clickpad, 5 contacts wsmouse0 at imt0 mux 0 The touchpad does not work yet. Let me know if you are interested in anything else from this machine. Thanks. Has anyone tested this on currently-working machines with ACPI attachment? I am more concerned about not breaking anything right now.
Re: inteldrm: reduce i2c busy-wait to 100us
On Wed, 11 Oct 2017 at 11:16:07 +0200, Mark Kettenis wrote: > > Date: Tue, 10 Oct 2017 15:42:26 -0500 > > From: joshua stein > > > > On my Kaby Lake laptop, running xbacklight or xrandr causes the > > audio and mouse cursor to pause briefly. This is because those > > codepaths do DRM operations that have to probe all of the available > > connectors, even disconnected ones. For HDMI, it does i2c > > operations that have to timeout. > > > > Reducing the DELAY() calls to 100us avoids this, while still making > > HDMI output work when it's actually connected. > > > > intel_gmbus_exec appears to be an OpenBSD-specific function. > > This will need careful testing on older hardware, especially with > multi-screen desktop setups. Has anyone tested this on multi-screen desktop setups?
dwiic: add pci attachment
Intel 100 Series laptops have the DesignWare I2C controller attaching via PCI instead of ACPI, so move the guts of dwiic(4) into ic/ and add dwiic_acpi and dwiic_pci files. Unfortunately the PCI attachment still needs to reach into ACPI to discover client devices. There is still an issue with interrupt setup on these machines (unrelated to dwiic as far as I can tell), where ioapic interrupts registered for client devices like ihidev never fire, but those for dwiic (via PCI) do. This diff sets a flag for PCI-attached dwiic devices so that ihidev can do polling for client devices, which will come in a separate diff. I need some tests on machines where dwiic/ihidev attaches over ACPI. Index: sys/arch/amd64/conf/GENERIC === RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v retrieving revision 1.447 diff -u -p -u -p -r1.447 GENERIC --- sys/arch/amd64/conf/GENERIC 28 Oct 2017 01:37:52 - 1.447 +++ sys/arch/amd64/conf/GENERIC 3 Nov 2017 16:56:20 - @@ -135,6 +135,7 @@ iic*at nviic? amdpm* at pci? # AMD-7xx/8111 and NForce SMBus controller iic* at amdpm? dwiic* at acpi?# DesignWare Synopsys i2c controller +dwiic* at pci? iic* at dwiic? itherm*at pci? # Intel 3400 Thermal Sensor Index: sys/conf/files === RCS file: /cvs/src/sys/conf/files,v retrieving revision 1.654 diff -u -p -u -p -r1.654 files --- sys/conf/files 3 Nov 2017 13:01:20 - 1.654 +++ sys/conf/files 3 Nov 2017 16:56:21 - @@ -524,6 +524,10 @@ file dev/spdmem.cspdmem device oaic: scsi file dev/ic/aic6250.coaic +# Synopsys DesignWare I2C controller +device dwiic: i2cbus +file dev/ic/dwiic.c dwiic + # legitimate pseudo-devices pseudo-device vnd: disk pseudo-device rd: disk Index: sys/dev/pci/files.pci === RCS file: /cvs/src/sys/dev/pci/files.pci,v retrieving revision 1.329 diff -u -p -u -p -r1.329 files.pci --- sys/dev/pci/files.pci 21 Jan 2017 10:58:15 - 1.329 +++ sys/dev/pci/files.pci 3 Nov 2017 16:56:21 - @@ -807,5 +807,9 @@ filedev/pci/xspd.c xspd attach virtio at pci with virtio_pci file dev/pci/virtio_pci.cvirtio_pci +# Synopsys DesignWare I2C Controller +attach dwiic at pci with dwiic_pci +file dev/pci/dwiic_pci.c dwiic_pci + include "dev/pci/files.agp" include "dev/pci/drm/files.drm" Index: sys/dev/pci/dwiic_pci.c === RCS file: sys/dev/pci/dwiic_pci.c diff -N sys/dev/pci/dwiic_pci.c --- /dev/null 1 Jan 1970 00:00:00 - +++ sys/dev/pci/dwiic_pci.c 3 Nov 2017 16:56:21 - @@ -0,0 +1,204 @@ +/* $OpenBSD$ */ +/* + * Synopsys DesignWare I2C controller + * PCI attachment + * + * Copyright (c) 2015-2017 joshua stein + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* 13.3: I2C Additional Registers Summary */ +#define LPSS_RESETS0x204 +#define LPSS_RESETS_I2C (1 << 0) | (1 << 1) +#define LPSS_RESETS_IDMA (1 << 2) +#define LPSS_ACTIVELTR 0x210 +#define LPSS_IDLELTR 0x214 +#define LPSS_CAPS 0x2fc +#define LPSS_CAPS_NO_IDMA (1 << 8) +#define LPSS_CAPS_TYPE_SHIFT 4 +#define LPSS_CAPS_TYPE_MASK (0xf << LPSS_CAPS_TYPE_SHIFT) + +intdwiic_pci_match(struct device *, void *, void *); +void dwiic_pci_attach(struct device *, struct device *, void *); +intdwiic_pci_activate(struct device *, int); +void dwiic_pci_bus_scan(struct device *, + struct i2cbus_attach_args *, void *); + +#include "acpi.h" +#if NACPI > 0 +struct aml_node *acpi_pci_match(struct device *dev, struct pci_attach_args *pa); +#endif + +struct cfattach dwiic_pci_ca = { + sizeof(struct dwiic_softc), + dwiic_pci_match, + dwiic_pci_attach, + NULL,
inteldrm: reduce i2c busy-wait to 100us
On my Kaby Lake laptop, running xbacklight or xrandr causes the audio and mouse cursor to pause briefly. This is because those codepaths do DRM operations that have to probe all of the available connectors, even disconnected ones. For HDMI, it does i2c operations that have to timeout. Reducing the DELAY() calls to 100us avoids this, while still making HDMI output work when it's actually connected. intel_gmbus_exec appears to be an OpenBSD-specific function. Index: sys/dev/pci/drm/i915/intel_i2c.c === RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_i2c.c,v retrieving revision 1.12 diff -u -p -u -p -r1.12 intel_i2c.c --- sys/dev/pci/drm/i915/intel_i2c.c30 Sep 2017 07:36:56 - 1.12 +++ sys/dev/pci/drm/i915/intel_i2c.c10 Oct 2017 20:32:59 - @@ -231,7 +231,7 @@ intel_gmbus_exec(void *cookie, i2c_op_t st = I915_READ(GMBUS2); if (st & (GMBUS_SATOER | GMBUS_HW_RDY)) break; - DELAY(1000); + DELAY(100); } if (st & GMBUS_SATOER) { bus_err = 1; @@ -254,7 +254,7 @@ intel_gmbus_exec(void *cookie, i2c_op_t st = I915_READ(GMBUS2); if (st & (GMBUS_SATOER | GMBUS_HW_RDY)) break; - DELAY(1000); + DELAY(100); } if (st & GMBUS_SATOER) { bus_err = 1; @@ -279,7 +279,7 @@ out: bus_err = 1; if ((st & GMBUS_ACTIVE) == 0) break; - DELAY(1000); + DELAY(100); } if (st & GMBUS_ACTIVE) return (ETIMEDOUT);
hidmt: add support for hybrid mode
This adds support for Hybrid mode for Windows Precision Touchpads (ihidev/imt). If yours only works with one finger, this should fix that. This also changes the way SET_REPORTs are sent to put the touchpad into touchpad mode, now as two bytes. This is needed on the touchpad on my Huawei and matches the bytes that Linux outputs. It also renames the internal hidmt_input struct to avoid conflicting with hidmt_input function. I'd appreciate tests on any machines with ihidev/imt to make sure this doesn't break. (These are three separate commits but are combined in one diff for testing.) Index: sys/dev/hid/hidmt.c === RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.3 diff -u -p -u -p -r1.3 hidmt.c --- sys/dev/hid/hidmt.c 8 Oct 2017 10:13:42 - 1.3 +++ sys/dev/hid/hidmt.c 8 Oct 2017 14:08:09 - @@ -4,6 +4,7 @@ * standard * * https://msdn.microsoft.com/en-us/library/windows/hardware/dn467314%28v=vs.85%29.aspx + * https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/touchscreen-packet-reporting-modes * * Copyright (c) 2016 joshua stein * @@ -167,7 +168,7 @@ hidmt_setup(struct device *self, struct hd = hid_start_parse(desc, dlen, hid_input); while (hid_get_item(hd, &h)) { - struct hidmt_input *input; + struct hidmt_data *input; if (h.report_ID != mt->sc_rep_input) continue; @@ -275,16 +276,16 @@ hidmt_detach(struct hidmt *mt, int flags } int -hidmt_set_input_mode(struct hidmt *mt, int mode) +hidmt_set_input_mode(struct hidmt *mt, uint16_t mode) { return mt->hidev_set_report(mt->sc_device, hid_feature, - mt->sc_rep_config, &mode, 1); + mt->sc_rep_config, &mode, 2); } void hidmt_input(struct hidmt *mt, uint8_t *data, u_int len) { - struct hidmt_input *hi; + struct hidmt_data *hi; struct hidmt_contact hc; int32_t d, firstu = 0; int contactcount = 0, seencontacts = 0, tips = 0, i, s, z; @@ -307,8 +308,29 @@ hidmt_input(struct hidmt *mt, uint8_t *d */ SIMPLEQ_FOREACH(hi, &mt->sc_inputs, entry) { if (hi->usage == HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTCOUNT)) - contactcount = hid_get_udata(data, len, - &hi->loc); + contactcount = hid_get_udata(data, len, &hi->loc); + } + + if (contactcount) + mt->sc_cur_contactcount = contactcount; + else { + /* + * "In Hybrid mode, the number of contacts that can be reported + * in one report is less than the maximum number of contacts + * that the device supports. For example, a device that supports + * a maximum of 4 concurrent physical contacts, can set up its + * top-level collection to deliver a maximum of two contacts in + * one report. If four contact points are present, the device + * can break these up into two serial reports that deliver two + * contacts each. + * + * "When a device delivers data in this manner, the Contact + * Count usage value in the first report should reflect the + * total number of contacts that are being delivered in the + * hybrid reports. The other serial reports should have a + * contact count of zero (0)." + */ + contactcount = mt->sc_cur_contactcount; } if (!contactcount) { @@ -373,7 +395,8 @@ hidmt_input(struct hidmt *mt, uint8_t *d /* these will only appear once per report */ case HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTCOUNT): - contactcount = d; + if (d) + contactcount = d; break; case HID_USAGE2(HUP_BUTTON, 0x01): mt->sc_button = (d != 0); Index: sys/dev/hid/hidmtvar.h === RCS file: /cvs/src/sys/dev/hid/hidmtvar.h,v retrieving revision 1.2 diff -u -p -u -p -r1.2 hidmtvar.h --- sys/dev/hid/hidmtvar.h 8 Oct 2017 10:13:42 - 1.2 +++ sys/dev/hid/hidmtvar.h 8 Oct 2017 14:08:09 - @@ -15,10 +15,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -struct hidmt_input { +struct hidmt_data { int32_t usage; struct hid_location loc; - SIMPLEQ_ENTRY(hidmt_input) entry; + SIMPLEQ_ENTRY(hidmt_data) entry; }; struct hidmt_contact { @@ -49,7 +49,7 @@ struct hidmt { int sc_rep_config; int sc_rep_cap; - SIMPLEQ_HEAD(, h
acpithinkpad fixes for brand new machines
Revision 1.50 of acpithinkpad.c made inteldrm defer to acpithinkpad for screen brightness adjustments instead of handling it natively. That was needed to avoid some synchronization issues on machines where the hardware buttons do the backlight adjustment on their own, and just notify acpithinkpad of the change. On brand new machines like the X1C5, the screen adjustment buttons don't do anything on their own and don't even notify acpithinkpad anymore, instead requiring a WMI driver to get notified. Since acpithinkpad is still forcing screen backlight changes to go through the proprietary ACPI interface, it is still limited to 10 levels of backlight adjustment which are oddly defined. I thought about just reverting 1.55 so that acpithinkpad wouldn't even bother attaching to these new machines which now use HID LEN0268, so that inteldrm could take over brightness adjustment and give you the full 100 levels of adjustment. However, controlling keyboard backlight through wscons still has to be done through acpithinkpad, so the driver still has to attach. As is, the driver was not getting notification of keyboard backlight changes either, so the "wsconsctl keyboard.backlight" value would get out of sync with the hardware if you adjusted the backlight with Fn+Space. This diff fixes the keyboard backlight events coming through, and also makes it not take over backlight adjustment on these new machines (LEN0268 and anything in the future). Eventually these machines will need a WMI driver to respond to other hardware keys and react accordingly, though many other kinds of laptops can also benefit from that driver. I'm not pushing to commit this before the lock, so it would be nice to have testing on a wide variety of ThinkPads to make sure the keyboard backlight change doesn't break anything. Index: sys/dev/acpi/acpithinkpad.c === RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.58 diff -u -p -u -p -r1.58 acpithinkpad.c --- sys/dev/acpi/acpithinkpad.c 12 Aug 2017 17:33:51 - 1.58 +++ sys/dev/acpi/acpithinkpad.c 8 Sep 2017 21:39:12 - @@ -41,6 +41,8 @@ #defineTHINKPAD_HKEY_VERSION1 0x0100 #defineTHINKPAD_HKEY_VERSION2 0x0200 +#defineTHINKPAD_KEYLIGHT_MASK 0x2 + #defineTHINKPAD_CMOS_VOLUME_DOWN 0x00 #defineTHINKPAD_CMOS_VOLUME_UP 0x01 #defineTHINKPAD_CMOS_VOLUME_MUTE 0x02 @@ -136,6 +138,7 @@ struct acpithinkpad_softc { const char *sc_thinklight_set; uint64_t sc_brightness; + int sc_fw_brightness; }; extern void acpiec_read(struct acpiec_softc *, u_int8_t, int, u_int8_t *); @@ -195,6 +198,17 @@ const char *acpithinkpad_hids[] = { 0 }; +/* + * Older machines which need backlight control done in firmware/ACPI. Newer + * machines rely on inteldrm to do adjustments since hardware keys don't come + * through here. + */ +const char *acpithinkpad_fw_hids[] = { + "IBM0068", + "LEN0068", + 0 +}; + int thinkpad_match(struct device *parent, void *match, void *aux) { @@ -272,6 +286,9 @@ thinkpad_attach(struct device *parent, s sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; + sc->sc_fw_brightness = acpi_matchhids(aa, acpithinkpad_fw_hids, + sc->sc_dev.dv_xname); + printf("\n"); #if NAUDIO > 0 && NWSKBD > 0 @@ -299,8 +316,8 @@ thinkpad_attach(struct device *parent, s wskbd_set_backlight = thinkpad_set_backlight; } - if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", - 0, NULL, &sc->sc_brightness) == 0) { + if (sc->sc_fw_brightness && aml_evalinteger(sc->sc_acpi, + sc->sc_devnode, "PBLG", 0, NULL, &sc->sc_brightness) == 0) { ws_get_param = thinkpad_get_param; ws_set_param = thinkpad_set_param; } @@ -323,6 +340,9 @@ thinkpad_enable_events(struct acpithinkp printf("%s: no MHKA\n", DEVNAME(sc)); return (1); } + + /* Make sure keyboard backlight events are enabled */ + mask |= THINKPAD_KEYLIGHT_MASK; /* Update hotkey mask */ bzero(args, sizeof(args));
acpibat: don't be strict about _BIX being too big
For some reason on at least the ThinkPad X1C 5th Gen, Lenovo makes _BIX return a package with size 21 instead of 20, adding an int at the end after the OEM string value (I'm guessing to be used as an OEM int value). The template that _BIX writes into: Name (BX0I, Package (0x15) { 0x01, 0x00, 0x, 0x, 0x01, 0x, 0x00, 0x00, 0x, 0x00017318, 0x, 0x, 0x03E8, 0x01F4, 0x, 0x, "", "", "", "", 0x00 }) As long as all of the _BIX fields we care about are there, don't be strict about the size. Index: sys/dev/acpi/acpibat.c === RCS file: /cvs/src/sys/dev/acpi/acpibat.c,v retrieving revision 1.65 diff -u -p -u -p -r1.65 acpibat.c --- sys/dev/acpi/acpibat.c 25 Jul 2017 21:32:07 - 1.65 +++ sys/dev/acpi/acpibat.c 3 Sep 2017 19:47:00 - @@ -332,7 +332,7 @@ acpibat_getbix(struct acpibat_softc *sc) if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BIX", 0, NULL, &res) == 0) { - if (res.length == 20) + if (res.length >= 20) sc->sc_use_bif = 0; else dnprintf(10, "%s: invalid _BIX (%d != 20)\n",
amd64: remove clock warning
Removes this useless error that appears on some modern machines: RTC BIOS diagnostic error ff Index: sys/arch/amd64/isa/clock.c === RCS file: /cvs/src/sys/arch/amd64/isa/clock.c,v retrieving revision 1.24 diff -u -p -u -p -r1.24 clock.c --- sys/arch/amd64/isa/clock.c 25 Jan 2017 08:23:50 - 1.24 +++ sys/arch/amd64/isa/clock.c 11 Aug 2017 21:08:43 - @@ -157,16 +157,10 @@ u_long rtclock_tval; void startclocks(void) { - int s; - mtx_enter(&timer_mutex); rtclock_tval = TIMER_DIV(hz); i8254_startclock(); mtx_leave(&timer_mutex); - - /* Check diagnostic status */ - if ((s = mc146818_read(NULL, NVRAM_DIAG)) != 0) /* XXX softc */ - printf("RTC BIOS diagnostic error %b\n", s, NVRAM_DIAG_BITS); } int
Re: acpibat: add _BIX support
On Sat, 22 Jul 2017 at 18:07:56 +0200, Mark Kettenis wrote: > > Date: Fri, 21 Jul 2017 23:31:28 -0500 > > From: joshua stein > > > > ACPI 4.0 deprecated _BIF for battery status, so some newer machines > > have _BIX instead which provides the same info plus some extra > > fields. > > > > I used some macro magic to make the diff less painful, and added a > > sensor for the new cycle count exported by _BIX which can be useful > > to see. > > Why not just switch to acpibat_bix and have acpibat_getbif() populate > that struct? That would make the diff much simpler. > > I had some code that did it the other way around (have > acpibat_getbix() populate the fields in struct acpibat_bif). That > would be acceptable too and result in an even simplet diff, but you'd > lost the extra sensor that you're adding. Don't know where I left > that diff though. It didn't work because the battery was behind smbus > or something. Index: dev/acpi/acpi.c === RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.329 diff -u -p -u -p -r1.329 acpi.c --- dev/acpi/acpi.c 20 Jul 2017 18:34:24 - 1.329 +++ dev/acpi/acpi.c 22 Jul 2017 18:01:34 - @@ -3096,12 +3096,12 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t if (bat->aba_softc->sc_bat_present == 0) continue; - if (bat->aba_softc->sc_bif.bif_last_capacity == 0) + if (bat->aba_softc->sc_bix.bix_last_capacity == 0) continue; bats++; rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / - bat->aba_softc->sc_bif.bif_last_capacity; + bat->aba_softc->sc_bix.bix_last_capacity; if (rem > 100) rem = 100; remaining += rem; Index: dev/acpi/acpibat.c === RCS file: /cvs/src/sys/dev/acpi/acpibat.c,v retrieving revision 1.63 diff -u -p -u -p -r1.63 acpibat.c --- dev/acpi/acpibat.c 12 Mar 2017 21:30:44 - 1.63 +++ dev/acpi/acpibat.c 22 Jul 2017 18:01:34 - @@ -44,7 +44,7 @@ const char *acpibat_hids[] = { ACPI_DEV_ void acpibat_monitor(struct acpibat_softc *); void acpibat_refresh(void *); -intacpibat_getbif(struct acpibat_softc *); +intacpibat_getbix(struct acpibat_softc *); intacpibat_getbst(struct acpibat_softc *); intacpibat_notify(struct aml_node *, int, void *); @@ -78,18 +78,22 @@ acpibat_attach(struct device *parent, st if ((sta & STA_BATTERY) != 0) { sc->sc_bat_present = 1; - acpibat_getbif(sc); + acpibat_getbix(sc); + + printf(": %s", sc->sc_devnode->name); + acpibat_getbst(sc); printf(": %s", sc->sc_devnode->name); - if (sc->sc_bif.bif_model[0]) - printf(" model \"%s\"", sc->sc_bif.bif_model); - if (sc->sc_bif.bif_serial[0]) - printf(" serial %s", sc->sc_bif.bif_serial); - if (sc->sc_bif.bif_type[0]) - printf(" type %s", sc->sc_bif.bif_type); - if (sc->sc_bif.bif_oem[0]) - printf(" oem \"%s\"", sc->sc_bif.bif_oem); + if (sc->sc_bix.bix_model[0]) + printf(" model \"%s\"", sc->sc_bix.bix_model); + if (sc->sc_bix.bix_serial[0]) + printf(" serial %s", sc->sc_bix.bix_serial); + if (sc->sc_bix.bix_type[0]) + printf(" type %s", sc->sc_bix.bix_type); + if (sc->sc_bix.bix_oem[0]) + printf(" oem \"%s\"", sc->sc_bix.bix_oem); + printf("\n"); } else { sc->sc_bat_present = 0; @@ -111,34 +115,34 @@ acpibat_monitor(struct acpibat_softc *sc { int type; - /* assume _BIF and _BST have been called */ + /* assume _BIF/_BIX and _BST have been called */ strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), sizeof(sc->sc_sensdev.xname)); - type = sc->sc_bif.bif_power_unit ? SENSOR_AMPHOUR : SENSOR_WATTHOUR; + type = sc->sc_bix.bix_power_unit ? SENSOR_AMPHOUR : SENSOR_WATTHOUR; strlcpy(sc->sc_sens[0].desc, "last full capacity", sizeof(sc->sc_sens[0].desc)); sc->sc_sens[0].type = type;
acpibat: add _BIX support
ACPI 4.0 deprecated _BIF for battery status, so some newer machines have _BIX instead which provides the same info plus some extra fields. I used some macro magic to make the diff less painful, and added a sensor for the new cycle count exported by _BIX which can be useful to see. Index: dev/acpi/acpi.c === RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.329 diff -u -p -u -p -r1.329 acpi.c --- dev/acpi/acpi.c 20 Jul 2017 18:34:24 - 1.329 +++ dev/acpi/acpi.c 22 Jul 2017 04:25:07 - @@ -3093,15 +3093,19 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t minutes = 0; rate = 0; SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { + u_int32_t last_capacity = (bat->aba_softc->sc_use_bix ? + bat->aba_softc->sc_bix.bix_last_capacity : + bat->aba_softc->sc_bif.bif_last_capacity); + if (bat->aba_softc->sc_bat_present == 0) continue; - if (bat->aba_softc->sc_bif.bif_last_capacity == 0) + if (last_capacity == 0) continue; bats++; rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / - bat->aba_softc->sc_bif.bif_last_capacity; + last_capacity; if (rem > 100) rem = 100; remaining += rem; Index: dev/acpi/acpibat.c === RCS file: /cvs/src/sys/dev/acpi/acpibat.c,v retrieving revision 1.63 diff -u -p -u -p -r1.63 acpibat.c --- dev/acpi/acpibat.c 12 Mar 2017 21:30:44 - 1.63 +++ dev/acpi/acpibat.c 22 Jul 2017 04:25:07 - @@ -29,6 +29,9 @@ #include #include +#define sc_bix_bif(var) (sc->sc_use_bix ? sc->sc_bix.bix_##var : sc->sc_bif.bif_##var) +#define BIX_BIF(var)(sc->sc_use_bix ? BIX_##var : BIF_##var) + intacpibat_match(struct device *, void *, void *); void acpibat_attach(struct device *, struct device *, void *); @@ -45,6 +48,7 @@ const char *acpibat_hids[] = { ACPI_DEV_ void acpibat_monitor(struct acpibat_softc *); void acpibat_refresh(void *); intacpibat_getbif(struct acpibat_softc *); +intacpibat_getbix(struct acpibat_softc *); intacpibat_getbst(struct acpibat_softc *); intacpibat_notify(struct aml_node *, int, void *); @@ -78,18 +82,25 @@ acpibat_attach(struct device *parent, st if ((sta & STA_BATTERY) != 0) { sc->sc_bat_present = 1; - acpibat_getbif(sc); - acpibat_getbst(sc); printf(": %s", sc->sc_devnode->name); - if (sc->sc_bif.bif_model[0]) - printf(" model \"%s\"", sc->sc_bif.bif_model); - if (sc->sc_bif.bif_serial[0]) - printf(" serial %s", sc->sc_bif.bif_serial); - if (sc->sc_bif.bif_type[0]) - printf(" type %s", sc->sc_bif.bif_type); - if (sc->sc_bif.bif_oem[0]) - printf(" oem \"%s\"", sc->sc_bif.bif_oem); + + if (acpibat_getbix(sc) == 0) + sc->sc_use_bix = 1; + else + acpibat_getbif(sc); + + acpibat_getbst(sc); + + if (sc_bix_bif(model)[0]) + printf(" model \"%s\"", sc_bix_bif(model)); + if (sc_bix_bif(serial)[0]) + printf(" serial %s", sc_bix_bif(serial)); + if (sc_bix_bif(type)[0]) + printf(" type %s", sc_bix_bif(type)); + if (sc_bix_bif(oem)[0]) + printf(" oem \"%s\"", sc_bix_bif(oem)); + printf("\n"); } else { sc->sc_bat_present = 0; @@ -111,34 +122,34 @@ acpibat_monitor(struct acpibat_softc *sc { int type; - /* assume _BIF and _BST have been called */ + /* assume _BIF/_BIX and _BST have been called */ strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), sizeof(sc->sc_sensdev.xname)); - type = sc->sc_bif.bif_power_unit ? SENSOR_AMPHOUR : SENSOR_WATTHOUR; + type = sc_bix_bif(power_unit) ? SENSOR_AMPHOUR : SENSOR_WATTHOUR; strlcpy(sc->sc_sens[0].desc, "last full capacity", sizeof(sc->sc_sens[0].desc)); sc->sc_sens[0].type = type; sensor_attach(&sc->sc_sensdev, &sc->sc_sens[0]); - sc->sc_sens[0].value = sc->sc_bif.bif_last_capacity * 1000; + sc->sc_sens[0].value = sc_bix_bif(last_capacity) * 1000; strlcpy(sc->sc_sens[1].desc, "warning capacity", sizeof(sc->sc_sens[1].desc)); sc->sc_sens[1].type = type; sensor_attach(&sc->sc_sensdev, &sc->sc_sens
rasops: fix virtual console initialization
Only copy the console buffer contents to a rasops virtual console if it's the first one (visible). Otherwise all of the other virtual consoles initialize with the trailing end of the kernel messages and then getty writes over them, like this: https://imgur.com/a/mAXKf Index: dev/rasops/rasops.c === RCS file: /cvs/src/sys/dev/rasops/rasops.c,v retrieving revision 1.44 diff -u -p -u -p -r1.44 rasops.c --- dev/rasops/rasops.c 15 Dec 2016 19:18:41 - 1.44 +++ dev/rasops/rasops.c 15 May 2017 01:40:22 - @@ -1398,7 +1398,7 @@ rasops_alloc_screen(void *v, void **cook scr->rs_crow = -1; scr->rs_ccol = -1; - if (ri->ri_bs) { + if (ri->ri_bs && scr->rs_visible) { memcpy(scr->rs_bs, ri->ri_bs, ri->ri_rows * ri->ri_cols * sizeof(struct wsdisplay_charcell)); } else {
Re: Add RTL8153 support to ure(4)
On Fri, 10 Mar 2017 at 20:54:39 +0100, Mark Kettenis wrote: > Fairly straightforward port of the changes made to the FreeBSD driver. > Like re(4) this has a fairly incestious relationship with rgephy(4) as > it needs a similar hack to read the media status register. > > Tests, especially on RTL8152 hardware, and OKs are welcome. Works fine on my Anker USB 3 ethernet device, which previously attached via cdce: cdce0 at uhub0 port 13 configuration 2 interface 0 "Realtek USB 10/100/1000 LAN" rev 3.00/30.00 addr 7 cdce0: address 00:e0:1e:81:01:39 now: ure0 at uhub0 port 12 configuration 1 interface 0 "Realtek USB 10/100/1000 LAN" rev 3.00/30.00 addr 7 ure0: ver 5c10, address 00:e0:1e:81:01:39 rgephy0 at ure0 phy 0: RTL8251 PHY, rev. 0