Re: hidmt: default to clickpad unless report says otherwise

2022-05-20 Thread joshua stein
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

2022-05-19 Thread joshua stein
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, , NULL)) {
d = hid_get_udata(rep, capsize, );
-   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, , NULL))
-   mt->sc_clickpad = 1;
+   if (d == 0x1)
+   mt->sc_clickpad = 0;
}
 
/*



DPTF sensors driver

2022-04-24 Thread joshua stein
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, ) == 0)
+   sc->sc_devtype = ACPIDPTFS_TYPE_SENSOR;
+   else if (aml_evalinteger((struct acpi_softc *)parent, aa->aaa_node,
+   "PTYP", 0, NULL, ) == 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

2022-04-20 Thread joshua stein
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

2022-04-20 Thread joshua stein
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, ) != 0) {
+   if (errno != ENOENT)
+   syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path);
+   globfree();
+   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();
 }
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

2022-04-15 Thread joshua stein
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

2022-04-15 Thread joshua stein
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, ) != 0) {
+   if (errno != ENOENT)
+   syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path);
+   globfree();
+   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();
 }



login_fbtab glob

2022-04-14 Thread joshua stein
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, ) != 0) {
+   if (errno != ENOENT)
+   syslog(LOG_ERR, "%s: glob(%s): %m", _PATH_FBTAB, path);
+   globfree();
+   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();
 }



Re: sndiod: -F does not switch back to preferred device

2021-12-09 Thread joshua stein
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=127990199813627=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();
 }
 
+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 hotplug_put_event(struct hotplug_event *);
-int hot

Re: iwx(4) 40MHz channel support

2021-10-14 Thread joshua stein
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

2021-08-23 Thread joshua stein
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

2021-08-22 Thread joshua stein
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

2021-08-18 Thread joshua stein
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

2021-05-30 Thread joshua stein
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, , );
+
+   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

2021-05-28 Thread joshua stein
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

2021-05-24 Thread joshua stein
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

2021-05-24 Thread joshua stein
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, >sc_loc_x, )) {
-   printf("\n%s: mouse has no X report\n", self->dv_xname);
-   return ENXIO;
-   }
+   hid_input, >sc_loc_x, ))
+   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, >sc_loc_y, )) {
-   printf("\n%s: mouse has no Y report\n", self->dv_xname);
-   return ENXIO;
-   }
+   hid_input, >sc_loc_y, ))
+   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

2021-05-12 Thread joshua stein
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=127990199813627=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();
 }
 
+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)

2021-04-14 Thread joshua stein
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

2021-03-26 Thread joshua stein
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, >type) != 0)
-   goto fail;
+   if (ioctl(pInfo->fd, WSMOUSEIO_GTYPE, >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

2021-03-05 Thread joshua stein
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, , 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, , );
-   if (umt_find_winptp_reports(uha->parent, desc, size, NULL))
+   if (umt_find_winptp_reports(uha->parent, desc, size, ,
+   , )) {
+   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_input = -1;
-   

ddb: resize when new console attaches

2021-02-02 Thread joshua stein
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 = _cons;
 
wsdisplay_console_initted = 1;
+
+#ifdef DDB
+   db_resize(type->ncols, type->nrows);
+#endif
 }
 
 /*



ims: claim to be a touchpad

2021-01-20 Thread joshua stein
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)?

2020-12-18 Thread joshua stein
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)

2020-09-07 Thread joshua stein
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)

2020-08-05 Thread joshua stein
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(>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

2020-07-02 Thread joshua stein
ent;
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, , );
-   if (imt_find_winptp_reports(iha->parent, desc, size, NULL))
+   if (imt_find_winptp_reports(iha->parent, desc, size, )) {
+   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)

2020-06-11 Thread joshua stein
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

2020-06-02 Thread joshua stein
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/ System

umstc: Microsoft Surface Type Cover driver

2020-05-30 Thread joshua stein
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

2020-05-30 Thread joshua stein
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

2020-05-17 Thread joshua stein
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

2020-02-06 Thread joshua stein
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, ) != -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

2020-02-06 Thread joshua stein
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, ) != -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

2020-02-06 Thread joshua stein
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, ) != -1) {
close(ptm.sfd);



posix_openpt: allow O_CLOEXEC

2020-02-05 Thread joshua stein
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, ) != -1) {
close(ptm.sfd);



Re: iwm(4): support for MSI-X

2019-11-20 Thread joshua stein
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

2019-11-16 Thread joshua stein
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

2019-11-16 Thread joshua stein
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

2019-10-13 Thread joshua stein
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_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_brightness) == 0)) {
ws_get_param = thinkpad_get_param;
ws_set_param = thinkpad_set_param;
}



acpivout: try to consistently adjust brightness by 5%

2019-10-13 Thread joshua stein
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

2019-09-20 Thread joshua stein
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

2019-08-10 Thread joshua stein
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

2019-07-19 Thread joshua stein
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();
 
-   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 = 
 
if (config_found(sc->sc_iic, , 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_timer)) {
+   DPRINTF(("%s: canceling polling\n",
+   sc->sc_dev.dv_xname));
+   timeout_del_barrier(>sc_timer);
+   }
+   if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER,
+   _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_timer))
+   timeout_add(>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_timer);
+   }
+
/*
 * XXX: force I2C_F_POLL for now to avoid dwiic interrupting
 * while we are interrupting
@@ 

Re: [Patch] Driver for Keyspan USA-19HS

2019-06-07 Thread joshua stein
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

2019-05-28 Thread joshua stein
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 {
> + 

ubcmtp: fix multi-finger on type4 devices

2019-05-25 Thread joshua stein
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

2019-04-08 Thread joshua stein
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

2019-03-17 Thread joshua stein
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

2019-03-16 Thread joshua stein
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();
 
-   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 = 
 
if (config_found(sc->sc_iic, , 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_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_timer))
-   timeout_set(>sc_timer, (void *)ihidev_intr, sc);
+   timeout_set(>sc_timer, (void *)ihidev_poll, sc);
if (!timeout_pending(>sc_timer))
timeout_add(>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

2019-03-16 Thread joshua stein
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

2019-03-15 Thread joshua stein
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_paa);
+   if (node != NULL) {
+   sc->sc_devnode = node;
+
+   dwiic_acpi_get_params(sc, "SSCN", >ss_hcnt, >ss_lcnt,
+   NULL);
+   dwiic_acpi_get_params(sc, "FMCN", >fs_hcnt, >fs_lcnt,
+   >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_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

2019-03-13 Thread joshua stein
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

2019-03-06 Thread joshua stein
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_brightness);
+   int ret;
+
+   ret = aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "PBLG", 0, NULL,
+   >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(, 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, , NULL);
+   ret = aml_evalname(sc->sc_acpi, sc->sc_devnode, "PBLS", 1, , 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

2019-03-05 Thread joshua stein
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_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_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_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, )) {
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, ))
break;
+
+   DPRINTF(("%s: event 0x%03llx\n", DEVNAME(sc), event));
if (event == 0)
break;
 
@@ 

Re: [PATCH] Add elan(4) touchpad driver

2018-11-08 Thread joshua stein
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(, 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 = 
> +
> + if (config_found(sc->sc_iic, , 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 ia;
> +
> 

Re: ims: match on HID touchscreens

2018-09-01 Thread joshua stein
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

2018-08-31 Thread joshua stein
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)

2018-08-25 Thread joshua stein
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

2018-08-24 Thread joshua stein
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, , 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, , 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.c,v

ubcmtp: fix multi-finger on type4 devices, pass in proper pressure

2018-08-15 Thread joshua stein
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)

2018-07-27 Thread joshua stein
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

2018-07-27 Thread joshua stein
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

2018-07-27 Thread joshua stein
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

2018-07-26 Thread 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.

(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

2018-07-23 Thread joshua stein
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(>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(_fb->base);



Re: realpath(3) on a dangling symlink

2018-06-27 Thread joshua stein
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

2018-06-27 Thread joshua stein
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;



rasops: implement scrollback for inteldrm and efifb

2018-04-16 Thread joshua stein
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_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_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 @@ int
 

sysctl(8): add -F option to print temps in freedom units

2018-02-19 Thread joshua stein
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

2018-01-02 Thread joshua stein
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

2017-11-16 Thread joshua stein

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

2017-11-16 Thread joshua stein
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(, 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 

Re: dwiic: add pci attachment

2017-11-11 Thread joshua stein
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 <j...@openbsd.org>
+ *
+ * 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_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_iot, >sc_ioh, NULL, , 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

2017-11-09 Thread joshua stein

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

2017-11-03 Thread joshua stein
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 <j...@openbsd.org>
> > 
> > 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

2017-11-03 Thread joshua stein
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 <j...@openbsd.org>
+ *
+ * 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,
+   

inteldrm: reduce i2c busy-wait to 100us

2017-10-10 Thread 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.


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

2017-10-08 Thread joshua stein
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 <j...@openbsd.org>
  *
@@ -167,7 +168,7 @@ hidmt_setup(struct device *self, struct 
 
hd = hid_start_parse(desc, dlen, hid_input);
while (hid_get_item(hd, )) {
-   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, , 1);
+   mt->sc_rep_config, , 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, >sc_inputs, entry) {
if (hi->usage == HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTCOUNT))
-   contactcount = hid_get_udata(data, len,
-   >loc);
+   contactcount = hid_get_udata(data, len, >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(, hidmt_input) sc_inputs;
+   SIMP

acpithinkpad fixes for brand new machines

2017-09-08 Thread joshua stein
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_brightness) == 0) {
+   if (sc->sc_fw_brightness && aml_evalinteger(sc->sc_acpi,
+   sc->sc_devnode, "PBLG", 0, NULL, >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

2017-09-03 Thread joshua stein
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,
) == 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

2017-08-11 Thread joshua stein
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(_mutex);
rtclock_tval = TIMER_DIV(hz);
i8254_startclock();
mtx_leave(_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

2017-07-22 Thread joshua stein
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 <j...@openbsd.org>
> > 
> > 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

2017-07-21 Thread 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.


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_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_sensdev, >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_sensdev, >sc_sens[1]);
-   

rasops: fix virtual console initialization

2017-05-14 Thread joshua stein
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)

2017-03-10 Thread joshua stein
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



acpisbs/acpibat

2017-03-06 Thread joshua stein
In case the DSDT provides interfaces for both a Smart Battery and a
normal one, probe for acpisbs first, if it attaches, make acpibat
not match.


Index: dev/acpi/acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.323
diff -u -p -u -p -r1.323 acpi.c
--- dev/acpi/acpi.c 2 Mar 2017 10:38:10 -   1.323
+++ dev/acpi/acpi.c 7 Mar 2017 02:34:37 -
@@ -116,6 +116,7 @@ voidacpi_enable_wakegpes(struct acpi_so
 intacpi_foundec(struct aml_node *, void *);
 intacpi_foundsony(struct aml_node *node, void *arg);
 intacpi_foundhid(struct aml_node *, void *);
+intacpi_foundsbs(struct aml_node *node, void *);
 intacpi_add_device(struct aml_node *node, void *arg);
 
 void   acpi_thread(void *);
@@ -1082,6 +1083,9 @@ acpi_attach(struct device *parent, struc
 
aml_walknodes(_root, AML_WALK_PRE, acpi_add_device, sc);
 
+   /* try to find smart battery first */
+   aml_find_node(_root, "_HID", acpi_foundsbs, sc);
+
/* attach battery, power supply and button devices */
aml_find_node(_root, "_HID", acpi_foundhid, sc);
 
@@ -2911,6 +2915,45 @@ acpi_foundvideo(struct aml_node *node, v
 
return (0);
 }
+
+int
+acpi_foundsbs(struct aml_node *node, void *arg)
+{
+   struct acpi_softc   *sc = (struct acpi_softc *)arg;
+   struct device   *self = (struct device *)arg;
+   char cdev[32], dev[32];
+   struct acpi_attach_args  aaa;
+   int64_t  sta;
+
+   if (acpi_parsehid(node, arg, cdev, dev, sizeof(dev)) != 0)
+   return (0);
+
+   if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, ))
+   sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
+
+   if ((sta & STA_PRESENT) == 0)
+   return (0);
+
+   acpi_attach_deps(sc, node->parent);
+
+   if (strcmp(dev, ACPI_DEV_SBS) != 0)
+   return (0);
+
+   if (node->parent->attached)
+   return (0);
+
+   memset(, 0, sizeof(aaa));
+   aaa.aaa_iot = sc->sc_iot;
+   aaa.aaa_memt = sc->sc_memt;
+   aaa.aaa_node = node->parent;
+   aaa.aaa_dev = dev;
+
+   config_found(self, , acpi_print);
+   node->parent->attached = 1;
+
+   return (0);
+}
+
 
 int
 acpiopen(dev_t dev, int flag, int mode, struct proc *p)
Index: dev/acpi/acpibat.c
===
RCS file: /cvs/src/sys/dev/acpi/acpibat.c,v
retrieving revision 1.62
diff -u -p -u -p -r1.62 acpibat.c
--- dev/acpi/acpibat.c  14 Mar 2015 03:38:46 -  1.62
+++ dev/acpi/acpibat.c  7 Mar 2017 02:34:37 -
@@ -54,6 +54,9 @@ acpibat_match(struct device *parent, voi
struct acpi_attach_args *aa = aux;
struct cfdata   *cf = match;
 
+   if (((struct acpi_softc *)parent)->sc_havesbs)
+   return (0);
+
/* sanity */
return (acpi_matchhids(aa, acpibat_hids, cf->cf_driver->cd_name));
 }
Index: dev/acpi/acpireg.h
===
RCS file: /cvs/src/sys/dev/acpi/acpireg.h,v
retrieving revision 1.38
diff -u -p -u -p -r1.38 acpireg.h
--- dev/acpi/acpireg.h  25 Feb 2017 20:09:20 -  1.38
+++ dev/acpi/acpireg.h  7 Mar 2017 02:34:37 -
@@ -748,10 +748,10 @@ struct acpi_ivrs {
 #define ACPI_DEV_MEMD  "PNP0C80"   /* Memory Device */
 #define ACPI_DEV_MOUSE "PNP0F13"   /* PS/2 Mouse */
 #define ACPI_DEV_SHC   "ACPI0001"  /* SMBus 1.0 Host Controller */
-#define ACPI_DEV_SMS1  "ACPI0002"  /* Smart Battery Subsystem */
+#define ACPI_DEV_SBS   "ACPI0002"  /* Smart Battery Subsystem */
 #define ACPI_DEV_AC"ACPI0003"  /* AC Device */
 #define ACPI_DEV_MD"ACPI0004"  /* Module Device */
-#define ACPI_DEV_SMS2  "ACPI0005"  /* SMBus 2.0 Host Controller */
+#define ACPI_DEV_SMBUS "ACPI0005"  /* SMBus 2.0 Host Controller */
 #define ACPI_DEV_GBD   "ACPI0006"  /* GPE Block Device */
 #define ACPI_DEV_PD"ACPI0007"  /* Processor Device */
 #define ACPI_DEV_ALSD  "ACPI0008"  /* Ambient Light Sensor Device */
Index: dev/acpi/acpisbs.c
===
RCS file: /cvs/src/sys/dev/acpi/acpisbs.c,v
retrieving revision 1.3
diff -u -p -u -p -r1.3 acpisbs.c
--- dev/acpi/acpisbs.c  7 Mar 2017 02:27:02 -   1.3
+++ dev/acpi/acpisbs.c  7 Mar 2017 02:34:37 -
@@ -144,7 +144,7 @@ struct cfdriver acpisbs_cd = {
 };
 
 const char *acpisbs_hids[] = {
-   "ACPI0002",
+   ACPI_DEV_SBS,
NULL
 };
 
@@ -211,6 +211,8 @@ acpisbs_attach(struct device *parent, st
 
aml_register_notify(sc->sc_devnode, aa->aaa_dev, acpisbs_notify,
sc, ACPIDEV_POLL);
+
+   sc->sc_acpi->sc_havesbs = 1;
 }
 
 void
Index: dev/acpi/acpivar.h
===
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v

Re: Xorg stipple

2017-02-26 Thread joshua stein
On Sun, 26 Feb 2017 at 10:43:50 +0100, Landry Breuil wrote:
> On Wed, Mar 09, 2016 at 05:09:13PM -0600, joshua stein wrote:
> > Is anyone seriously finding video/Xorg bugs through the default X
> > stipple pattern anymore?  Xorg changed the default to draw a black
> > background a while ago (with stipple enabled using the -retro flag),
> > but we have this local change that reverted it while adding a silly
> > -retard flag in order to show the black background.
> > 
> > I think we can finally stop partying like it's 1989 (vax is dead,
> > after all) and have X show a solid black background by default.
> 
> Reviving this thread because everyone likes to party like it's
> 1989^W^W^W^Wthe smell of a sunday morning bikeshed From what i
> understand, we default to the -retro mode, that option is #ifndef'ed
> out, but Xserver(1) still mentions it. We instead provide (since xserver
> 1.6.4, 8 years ago) an undocumented -retard option which is supposed to
> have the default 'black background' behaviour. And then, there's -br
> flag.
> 
> So.. should we fix the code (from what i understood in the thread,
> there was opposition) or the manpage ?
> Or document (where?) that one can use xsetroot -solid in
> /etc/X11/xdm/Xsetup_0 to paint the default xdm/X background to its
> own bikeshed color ?

While I still think we should get rid of the stipple by default, I
propose this diff to xdm which paints the background black after X
fully starts up.

The stipple pattern will still appear briefly, to bring
enlightenment to all of those lost souls troubleshooting their X
startup problems in 2017 without consulting /var/log/Xorg.0.log, or
those using startx because they like the stipple and fvwm.  But once
X has loaded far enough to start xdm, it will paint the background
black.


diff --git app/xdm/config/Xsetup_0 app/xdm/config/Xsetup_0
index a24818c9d..7ff2260ee 100644
--- app/xdm/config/Xsetup_0
+++ app/xdm/config/Xsetup_0
@@ -1,5 +1,8 @@
 #!/bin/sh
 # $OpenBSD: Xsetup_0,v 1.3 2010/03/28 09:33:02 matthieu Exp $
+
+xsetroot -solid black
+
 if [ "$DISPLAY" = ":0" -o "$DISPLAY" = ":0.0" ]
 then
xconsole -geometry 480x130-0-0 -daemon -notify -verbose -fn fixed 
-exitOnFail



acpithinkpad: new hid

2017-02-25 Thread joshua stein
New ThinkPads use a different ACPI HID.


Index: sys/dev/acpi/acpireg.h
===
RCS file: /cvs/src/sys/dev/acpi/acpireg.h,v
retrieving revision 1.36
diff -u -p -u -p -r1.36 acpireg.h
--- sys/dev/acpi/acpireg.h  10 Jul 2016 20:36:41 -  1.36
+++ sys/dev/acpi/acpireg.h  25 Feb 2017 19:07:28 -
@@ -766,6 +766,7 @@ struct acpi_ivrs {
 #define ACPI_DEV_ASUS1 "ATK0100"   /* ASUS Special Device */
 #define ACPI_DEV_IBM   "IBM0068"   /* IBM ThinkPad support */
 #define ACPI_DEV_LENOVO"LEN0068"   /* Lenovo ThinkPad support */
+#define ACPI_DEV_LENOVO2 "LEN0268" /* Lenovo ThinkPad support */
 #define ACPI_DEV_ASUSAIBOOSTER "ATK0110"   /* ASUSTeK AI Booster */
 #define ACPI_DEV_TOSHIBA_LIBRETTO  "TOS6200"   /* Toshiba Libretto 
support */
 #define ACPI_DEV_TOSHIBA_DYNABOOK  "TOS6207"   /* Toshiba Dynabook 
support */
Index: sys/dev/acpi/acpithinkpad.c
===
RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v
retrieving revision 1.54
diff -u -p -u -p -r1.54 acpithinkpad.c
--- sys/dev/acpi/acpithinkpad.c 7 Feb 2017 05:18:07 -   1.54
+++ sys/dev/acpi/acpithinkpad.c 25 Feb 2017 19:07:28 -
@@ -181,7 +181,10 @@ struct cfdriver acpithinkpad_cd = {
 };
 
 const char *acpithinkpad_hids[] = {
-   ACPI_DEV_IBM, ACPI_DEV_LENOVO, 0
+   ACPI_DEV_IBM,
+   ACPI_DEV_LENOVO,
+   ACPI_DEV_LENOVO2,
+   0
 };
 
 int



Re: inteldrm: setup backlight pwm alternate increment on backlight enable

2017-02-20 Thread joshua stein
On Fri, 10 Feb 2017 at 10:46:08 +0100, Peter Hessler wrote:
> On 2017 Feb 10 (Fri) at 11:52:20 +1100 (+1100), Jonathan Gray wrote:
> :On Thu, Feb 09, 2017 at 06:39:13PM -0600, joshua stein wrote:
> :> I have no idea why there are chickens involved, but this fixes the
> :> problem on at least the MacBookAir7,1 (Broadwell) where upon S3
> :> resume, the backlight value is treated as 0 or 100 despite reporting
> :> intermediate values, so if the backlight value was anything other
> :> than 100 at suspend time, the screen will stay off upon resume.
> :
> :Chicken bits are overrides for functions like clock gating, if it turns
> :out there is a hardware bug in a particular feature these bits are used
> :to disable them.
> :
> :This diff seems reasonable but it would be nice to get some tests
> :on non-apple broadwell hardware.
> :
> 
> Tested on a broadwell Thinkpad x250, seems fine.  Changed the brightness
> to 40%, then did a few suspend-resumes.

Anyone else have any reports testing this diff?



speed up rasops32

2017-02-19 Thread joshua stein
Some EFI framebuffers are very slow, so rather than sending every
pixel of a character one at a time, send one row at a time.

Under VMWare fusion, this change makes a kernel boot to userland
more than 10 seconds faster.

It also helps a noticeable bit on my MacBook Air before inteldrm
takes over.


Index: sys/dev/rasops/rasops32.c
===
RCS file: /cvs/src/sys/dev/rasops/rasops32.c,v
retrieving revision 1.7
diff -u -p -u -p -r1.7 rasops32.c
--- sys/dev/rasops/rasops32.c   28 Aug 2010 12:48:14 -  1.7
+++ sys/dev/rasops/rasops32.c   19 Feb 2017 16:34:28 -
@@ -69,6 +69,7 @@ rasops32_putchar(void *cookie, int row, 
struct rasops_info *ri;
int32_t *dp, *rp;
u_char *fr;
+   uint32_t buffer[64];
 
ri = (struct rasops_info *)cookie;
 
@@ -90,12 +91,13 @@ rasops32_putchar(void *cookie, int row, 
clr[1] = ri->ri_devcmap[(attr >> 24) & 0xf];
 
if (uc == ' ') {
+   for (cnt = 0; cnt < width; cnt++)
+   buffer[cnt] = clr[0];
while (height--) {
dp = rp;
DELTA(rp, ri->ri_stride, int32_t *);
 
-   for (cnt = width; cnt; cnt--)
-   *dp++ = clr[0];
+   memcpy(dp, buffer, width << 2);
}
} else {
uc -= ri->ri_font->firstchar;
@@ -109,10 +111,11 @@ rasops32_putchar(void *cookie, int row, 
fr += fs;
DELTA(rp, ri->ri_stride, int32_t *);
 
-   for (cnt = width; cnt; cnt--) {
-   *dp++ = clr[(fb >> 31) & 1];
+   for (cnt = 0; cnt < width; cnt++) {
+   buffer[cnt] = clr[(fb >> 31) & 1];
fb <<= 1;
}
+   memcpy(dp, buffer, width << 2);
}
}
 



Re: acpi: pretend to be Darwin on Apple hardware

2017-02-10 Thread joshua stein
On Thu, 09 Feb 2017 at 18:30:59 -0600, joshua stein wrote:
> Without this, my MacBook Air won't suspend properly (hangs calling
> _PTS) and a similar change in Linux from 2014 (commit
> 7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334) notes that upon resume,
> the Thunderbolt ports won't be powered up without pretending to be
> Darwin.

One regression that this introduces is that acpibat no longer
attaches, because _STA on the PNP0C0A device returns 0 when the OS
is Darwin, expecting it to instead attach to the ACPI Smart Battery
Subsystem device (ACPI0002).

I'm looking into what it will take to write an ACPI smart battery
driver.



asmc: restore keyboard backlight on resume

2017-02-09 Thread joshua stein
After resume, the keyboard backlight is still off, so restore it
(this was also helpful to figure out the machine was actually
resuming).


Index: sys/dev/isa/asmc.c
===
RCS file: /cvs/src/sys/dev/isa/asmc.c,v
retrieving revision 1.30
diff -u -p -u -p -r1.30 asmc.c
--- sys/dev/isa/asmc.c  22 Apr 2016 20:45:53 -  1.30
+++ sys/dev/isa/asmc.c  10 Feb 2017 00:40:15 -
@@ -92,6 +92,7 @@ void  asmc_update(void *);
 intasmc_match(struct device *, void *, void *);
 void   asmc_attach(struct device *, struct device *, void *);
 intasmc_detach(struct device *, int);
+intasmc_activate(struct device *, int);
 
 /* wskbd hook functions */
 void   asmc_backlight(void *);
@@ -101,7 +102,7 @@ extern int (*wskbd_get_backlight)(struct
 extern int (*wskbd_set_backlight)(struct wskbd_backlight *);
 
 const struct cfattach asmc_ca = {
-   sizeof(struct asmc_softc), asmc_match, asmc_attach
+   sizeof(struct asmc_softc), asmc_match, asmc_attach, NULL, asmc_activate
 };
 
 struct cfdriver asmc_cd = {
@@ -355,6 +356,20 @@ asmc_detach(struct device *self, int fla
 
task_del(systq, >sc_task_backlight);
asmc_try(sc, ASMC_WRITE, "LKSB", buf, 2);
+   return 0;
+}
+
+int
+asmc_activate(struct device *self, int act)
+{
+   struct asmc_softc *sc = (struct asmc_softc *)self;
+
+   switch (act) {
+   case DVACT_WAKEUP:
+   asmc_backlight(sc);
+   break;
+   }
+
return 0;
 }
 



inteldrm: setup backlight pwm alternate increment on backlight enable

2017-02-09 Thread joshua stein
I have no idea why there are chickens involved, but this fixes the
problem on at least the MacBookAir7,1 (Broadwell) where upon S3
resume, the backlight value is treated as 0 or 100 despite reporting
intermediate values, so if the backlight value was anything other
than 100 at suspend time, the screen will stay off upon resume.

This is backported from Linux commits
32b421e79e6b546da1d469f1229403ac9142d695 and
e29aff05f239f8dd24e9ee7816fd96726e20105a which were noted in
freedesktop.org bug 67454.

This and the previous ACPI diff get suspend and resume working on
the MacBook Air.


Index: sys/dev/pci/drm/i915/i915_reg.h
===
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_reg.h,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 i915_reg.h
--- sys/dev/pci/drm/i915/i915_reg.h 25 Sep 2015 16:15:19 -  1.11
+++ sys/dev/pci/drm/i915/i915_reg.h 10 Feb 2017 00:39:02 -
@@ -4540,9 +4540,11 @@
 #define  FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 
2)))
 #define  FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2)))
 #define  FDI_BC_BIFURCATION_SELECT (1 << 12)
+#define  SPT_PWM_GRANULARITY   (1<<0)
 #define SOUTH_CHICKEN2 0xc2004
 #define  FDI_MPHY_IOSFSB_RESET_STATUS  (1<<13)
 #define  FDI_MPHY_IOSFSB_RESET_CTL (1<<12)
+#define  LPT_PWM_GRANULARITY   (1<<5)
 #define  DPLS_EDP_PPS_FIX_DIS  (1<<0)
 
 #define _FDI_RXA_CHICKEN 0xc200c
Index: sys/dev/pci/drm/i915/intel_drv.h
===
RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_drv.h,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 intel_drv.h
--- sys/dev/pci/drm/i915/intel_drv.h9 Dec 2015 05:17:44 -   1.9
+++ sys/dev/pci/drm/i915/intel_drv.h10 Feb 2017 00:39:02 -
@@ -168,6 +168,7 @@ struct intel_panel {
bool enabled;
bool combination_mode;  /* gen 2/4 only */
bool active_low_pwm;
+   bool alternate_pwm_increment;   /* lpt+ */
struct backlight_device *device;
} backlight;
 };
Index: sys/dev/pci/drm/i915/intel_panel.c
===
RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_panel.c,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 intel_panel.c
--- sys/dev/pci/drm/i915/intel_panel.c  23 Sep 2015 23:12:12 -  1.11
+++ sys/dev/pci/drm/i915/intel_panel.c  10 Feb 2017 00:39:02 -
@@ -611,7 +611,7 @@ static void bdw_enable_backlight(struct 
struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_panel *panel = >panel;
-   u32 pch_ctl1, pch_ctl2;
+   u32 pch_ctl1, pch_ctl2, schicken;
 
pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
@@ -620,6 +620,22 @@ static void bdw_enable_backlight(struct 
I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
}
 
+   if (HAS_PCH_LPT(dev)) {
+   schicken = I915_READ(SOUTH_CHICKEN2);
+   if (panel->backlight.alternate_pwm_increment)
+   schicken |= LPT_PWM_GRANULARITY;
+   else
+   schicken &= ~LPT_PWM_GRANULARITY;
+   I915_WRITE(SOUTH_CHICKEN2, schicken);
+   } else {
+   schicken = I915_READ(SOUTH_CHICKEN1);
+   if (panel->backlight.alternate_pwm_increment)
+   schicken |= SPT_PWM_GRANULARITY;
+   else
+   schicken &= ~SPT_PWM_GRANULARITY;
+   I915_WRITE(SOUTH_CHICKEN1, schicken);
+   }
+
pch_ctl2 = panel->backlight.max << 16;
I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
 
@@ -956,6 +972,13 @@ static int bdw_setup_backlight(struct in
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_panel *panel = >panel;
u32 pch_ctl1, pch_ctl2, val;
+   bool alt;
+
+   if (HAS_PCH_LPT(dev))
+   alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
+   else
+   alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
+   panel->backlight.alternate_pwm_increment = alt;
 
pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;



acpi: pretend to be Darwin on Apple hardware

2017-02-09 Thread joshua stein
When running on machines with a hw_vendor of "Apple Inc." or "Apple
Computer, Inc.", only return 1 for an OSI check of "Darwin" and not
the other Windows variants.

Code in the AML of the MacBookAir7,1 (most likely all Macs) does
much different things when running on Darwin systems, but the AML
that checks for Darwin does this:

OSYS = 0x07DC
If (CondRefOf (\_OSI, Local0))
{
If (_OSI ("Darwin"))
{
OSYS = 0x2710
}

If (\_OSI ("Linux"))
{
OSYS = 0x03E8
}

If (\_OSI ("Windows 2009"))
{
OSYS = 0x07D9
}
[...]

So we can't just add Darwin to aml_valid_osi.

Without this, my MacBook Air won't suspend properly (hangs calling
_PTS) and a similar change in Linux from 2014 (commit
7bc5a2bad0b8d9d1ac9f7b8b33150e4ddf197334) notes that upon resume,
the Thunderbolt ports won't be powered up without pretending to be
Darwin.

I tested this with a Thunderbolt ethernet device and it works
properly before and after suspend.  Hot-plugging the Thunderbolt
ethernet device after boot no longer prints these messages:

ppb5 at pci4 dev 0 function 0 vendor "Intel", unknown product 0x156b rev 
0x00
pci6 at ppb5 bus 6
ppb6 at pci6 dev 0 function 0 vendor "Intel", unknown product 0x156b rev 
0x00: not configured by system firmware
ppb7 at pci6 dev 3 function 0 vendor "Intel", unknown product 0x156b rev 
0x00: not configured by system firmware
ppb8 at pci6 dev 4 function 0 vendor "Intel", unknown product 0x156b rev 
0x00: not configured by system firmware
ppb9 at pci6 dev 5 function 0 vendor "Intel", unknown product 0x156b rev 
0x00: not configured by system firmware
ppb10 at pci6 dev 6 function 0 vendor "Intel", unknown product 0x156b rev 
0x00: not configured by system firmware


Index: sys/dev/acpi/dsdt.c
===
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.230
diff -u -p -u -p -r1.230 dsdt.c
--- sys/dev/acpi/dsdt.c 14 Jan 2017 11:32:00 -  1.230
+++ sys/dev/acpi/dsdt.c 10 Feb 2017 00:31:02 -
@@ -106,6 +106,8 @@ void_aml_die(const char *fn, int 
line
 void aml_notify_task(void *, int);
 void acpi_poll_notify_task(void *, int);
 
+extern char*hw_vendor;
+
 /*
  * @@@: Global variables
  */
@@ -1505,6 +1507,21 @@ aml_callosi(struct aml_scope *scope, str
struct aml_value *fa;
 
fa = aml_getstack(scope, AMLOP_ARG0);
+
+   if (hw_vendor != NULL &&
+   (strcmp(hw_vendor, "Apple Inc.") == 0 ||
+   strcmp(hw_vendor, "Apple Computer, Inc.") == 0)) {
+   if (strcmp(fa->v_string, "Darwin") == 0) {
+   dnprintf(10,"osi: returning 1 for %s on %s hardware\n",
+   fa->v_string, hw_vendor);
+   result = 1;
+   } else
+   dnprintf(10,"osi: on %s hardware, but ignoring %s\n",
+   hw_vendor, fa->v_string);
+
+   return aml_allocvalue(AML_OBJTYPE_INTEGER, result, NULL);
+   }
+
for (idx=0; !result && aml_valid_osi[idx] != NULL; idx++) {
dnprintf(10,"osi: %s,%s\n", fa->v_string, aml_valid_osi[idx]);
result = !strcmp(fa->v_string, aml_valid_osi[idx]);



Re: acpiec: handle burst mode failure

2016-08-12 Thread joshua stein
On Fri, 08 Jul 2016 at 18:51:17 -0500, joshua stein wrote:
> If the EC fails to go into burst mode for whatever reason, the Burst
> Acknowledge byte will not be there to read, which means the status
> won't have EC_STAT_OBF, which means acpiec_wait will spin forever,
> hanging the machine.
> 
> This at least gets us moving again, ignoring the failure to enter
> burst mode.

That patch was put into the latest snapshot (but not yet in CVS) and
some people are seeing fallout from it like strange thermal and
battery status readings.

This is a different patch which just doesn't bother with burst mode
unless the transfer is big.  This should match how Linux and FreeBSD
behave.  I have at least one confirmation that this fixes things on
the ThinkPad X260.

Anyone else that is seeing strangeness on the latest snapshot, I ask
that you try this patch against -current and see if your issues go
away.


Index: sys/dev/acpi/acpiec.c
===
RCS file: /cvs/src/sys/dev/acpi/acpiec.c,v
retrieving revision 1.53
diff -u -p -u -r1.53 acpiec.c
--- sys/dev/acpi/acpiec.c   7 May 2016 18:03:36 -   1.53
+++ sys/dev/acpi/acpiec.c   11 Aug 2016 20:06:54 -
@@ -218,10 +218,12 @@ acpiec_read(struct acpiec_softc *sc, u_i
 */
dnprintf(20, "%s: read %d, %d\n", DEVNAME(sc), (int)addr, len);
sc->sc_ecbusy = 1;
-   acpiec_burst_enable(sc);
+   if (len > 1)
+   acpiec_burst_enable(sc);
for (reg = 0; reg < len; reg++)
buffer[reg] = acpiec_read_1(sc, addr + reg);
-   acpiec_burst_disable(sc);
+   if (len > 1)
+   acpiec_burst_disable(sc);
sc->sc_ecbusy = 0;
 }
 
@@ -237,10 +239,12 @@ acpiec_write(struct acpiec_softc *sc, u_
 */
dnprintf(20, "%s: write %d, %d\n", DEVNAME(sc), (int)addr, len);
sc->sc_ecbusy = 1;
-   acpiec_burst_enable(sc);
+   if (len > 1)
+   acpiec_burst_enable(sc);
for (reg = 0; reg < len; reg++)
acpiec_write_1(sc, addr + reg, buffer[reg]);
-   acpiec_burst_disable(sc);
+   if (len > 1)
+   acpiec_burst_disable(sc);
sc->sc_ecbusy = 0;
 }
 



Re: quiet legacy drivers on amd64

2016-08-02 Thread joshua stein
On Tue, 02 Aug 2016 at 12:30:51 +0200, Joerg Jung wrote:
> 
> > Am 01.08.2016 um 23:14 schrieb joshua stein <j...@openbsd.org>:
> > 
> > are these complaints really helpful on modern machines?
> 
> Can't speak for clock. But I tend to not like this for nvram.
> IMHO, even with recent HW this is a valid concern and reminder
> that someone should handle setting of the nvram options correctly.

Who is that someone, and what nvram options are they supposed to
set?

jcs@cvs:~> grep 'nvram: invalid checksum' /var/log/dmesglog* | wc -l
 308

jcs@cvs:~> grep 'clock: unknown CMOS layout' /var/log/dmesglog* | wc -l
 362



Re: acpiec: handle burst mode failure

2016-07-14 Thread joshua stein
On Thu, 14 Jul 2016 at 16:31:32 -0500, joshua stein wrote:
> Also, I just checked FreeBSD and they appear to do something similar
> to my patch, where they check that the EC burst mode flag is set in
> the status after trying to enable it:
> 
> https://github.com/freebsd/freebsd/blob/master/sys/dev/acpica/acpi_ec.c#L933
> 
> before actually trying to read the ACK:
> 
> https://github.com/freebsd/freebsd/blob/master/sys/dev/acpica/acpi_ec.c#L775

Interestingly it looks like FreeBSD used to have burst mode off by
default because of problems with certain machines, then enabled it
after adding that check for the status being on:

https://github.com/freebsd/freebsd/commit/7eb821d885e98115ff7a592adc00c4dbc05109cc

but then went back to disabling it by default in 2007 because of
continued problems with certain hardware, and it remains off by
default:

https://github.com/freebsd/freebsd/commit/a8ba35fb0023bb456954993d3c55712666b50d13

I wonder why we haven't seen (m)any problems with it being on by
default.



Re: acpiec: handle burst mode failure

2016-07-14 Thread joshua stein
On Sat, 09 Jul 2016 at 16:32:15 -0700, Philip Guenther wrote:
> No newer bios for this thing?  :-(

It is actually the open-source Chrome EC found on the Chromebook
Pixel (among others), and according to the source code for the
version on this machine, it did not implement burst mode in its ACPI
interface.

They eventually added support for it later, but for any EC that does
not support burst mode, I think this patch does the right thing by
checking that burst mode actually turns on before waiting for the
ack byte.

> > That's why the diff also includes the change to acpiec_write_cmd to
> > wait until IBF is 0, so it won't get to that new status check until
> > the controller has processed the EC_CMD_BE fully.
> 
> I don't think the spec guarantees that implication, though it may be
> true in practice.
> 
> 
> 
> Wonder what Windows and Linux do on this thing.

Linux doesn't even enable burst mode unless busy polling is enabled
(which is only turned on when passed as a kernel boot flag), or when
the read/write length is more than 8.

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/ec.c#n1195

(I think this is why they didn't bother implementing burst mode in
the ACPI interface of the Chrome EC, since it usually just runs
Linux and Linux doesn't usually try burst mode (and most other
device interfaces for this machine use direct I2C/LPC interfaces to
the EC instead of through ACPI.))

Also, I just checked FreeBSD and they appear to do something similar
to my patch, where they check that the EC burst mode flag is set in
the status after trying to enable it:

https://github.com/freebsd/freebsd/blob/master/sys/dev/acpica/acpi_ec.c#L933

before actually trying to read the ACK:

https://github.com/freebsd/freebsd/blob/master/sys/dev/acpica/acpi_ec.c#L775

> Anyway, this diff would need to be tested broadly on *unaffected*
> hardware to gain confidence it doesn't hurt some box that doesn't have
> this brokeness.

Yeah, I'll probably just disable acpicbkbd for the 6.0 release
because it requires talking to the EC and will just hang the kernel
on Chromebooks with a Chrome EC.



Re: acpiec: handle burst mode failure

2016-07-09 Thread joshua stein
On Fri, 08 Jul 2016 at 22:34:34 -0700, Philip Guenther wrote:
> On Fri, Jul 8, 2016 at 4:51 PM, joshua stein <j...@openbsd.org> wrote:
> > If the EC fails to go into burst mode for whatever reason, the Burst
> > Acknowledge byte will not be there to read, which means the status
> > won't have EC_STAT_OBF, which means acpiec_wait will spin forever,
> > hanging the machine.
> >
> > This at least gets us moving again, ignoring the failure to enter
> > burst mode.
> 
> Is it truly failing to enter burst mode, or are we just not doing the
> dance to enter correctly?  Looks like we should be waiting for an SCI
> and checking for a burst acknowledge byte?

All subsequent status fetches show that burst is not on.

> ...
> > @@ -196,7 +197,10 @@ void
> >  acpiec_burst_enable(struct acpiec_softc *sc)
> >  {
> > acpiec_write_cmd(sc, EC_CMD_BE);
> > -   acpiec_read_data(sc);
> > +   if (acpiec_status(sc) & (EC_STAT_BURST|EC_STAT_OBF))
> > +   acpiec_read_data(sc);
> > +   else
> > +   dnprintf(10, "%s: failed to enter burst mode\n", 
> > DEVNAME(sc));
> >  }
> 
> So if it doesn't immediately set either the burst or OBF flag then
> we'll continue on without reading the data?  That's going to break
> systems where EC isn't always fast to respond, no?

That's why the diff also includes the change to acpiec_write_cmd to
wait until IBF is 0, so it won't get to that new status check until
the controller has processed the EC_CMD_BE fully.



  1   2   >