On my Lenovo Yoga12, the touchscreen** will go into low power mode or some
such if I leave the system alone to make dinner or something productive
like that. At that point the wsmouse device for it vanishes and the X
server sees an infinite stream of EIO errors which it handles....by
looping and filling /var/log/Xorg.0.log! Thanks, but that's a horrible
behavior and unproductive in every way.
So every time I upgrade my X sets I run out of space in /var, then
remember to go back and rebuild the xf86-input-ws driver with the patch
below and life is good. Until I next upgrade.
Yes, the wsmouse or wscons, or maybe ums driver could handle this better,
but can the ws X driver stop behaving badly on EIO?
Philip Guenther
** which I do periodically find useful, so suggestions to disable it will
be ignored
Index: driver/xf86-input-ws/src/ws.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-input-ws/src/ws.c,v
retrieving revision 1.62
diff -u -p -r1.62 ws.c
--- driver/xf86-input-ws/src/ws.c 29 Aug 2015 08:48:29 -0000 1.62
+++ driver/xf86-input-ws/src/ws.c 16 Oct 2016 23:47:01 -0000
@@ -427,6 +427,11 @@ wsDeviceOn(DeviceIntPtr pWS)
}
}
}
+ if (priv->remove_timer == NULL) {
+ /* allocate here where it's safe */
+ priv->remove_timer = TimerSet(priv->remove_timer,
+ 0, 0, NULL, NULL);
+ }
xf86AddEnabledDevice(pInfo);
wsmbEmuOn(pInfo);
pWS->public.on = TRUE;
@@ -457,18 +462,41 @@ wsDeviceOff(DeviceIntPtr pWS)
pWS->public.on = FALSE;
}
+/*
+ * Called as an OsTimer() callback to remove the device while xf86Wakeup()
+ * isn't playing with the list.
+ */
+static CARD32
+wsRemoveMouse(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ InputInfoPtr pInfo = (InputInfoPtr) arg;
+
+ xf86DisableDevice(pInfo->dev, TRUE);
+
+ return 0; /* don't set to run again */
+}
+
static size_t
wsReadEvents(InputInfoPtr pInfo)
{
WSDevicePtr priv = (WSDevicePtr)pInfo->private;
ssize_t len;
+ int err;
priv->events_count = priv->events_pos = 0;
len = read(pInfo->fd, priv->events, sizeof(priv->events));
if (len < 0) {
- if (errno != EAGAIN)
+ err = errno;
+ if (err == EIO) {
+ xf86IDrvMsg(pInfo, X_ERROR,
+ "device no longer present - removing: %s\n",
+ strerror(err));
+ xf86RemoveEnabledDevice(pInfo);
+ priv->remove_timer = TimerSet(priv->remove_timer, 0, 1,
+ wsRemoveMouse, pInfo);
+ } else if (err != EAGAIN)
xf86IDrvMsg(pInfo, X_ERROR, "read error %s\n",
- strerror(errno));
+ strerror(err));
} else if (len % sizeof(struct wscons_event)) {
xf86IDrvMsg(pInfo, X_ERROR,
"read error, invalid number of bytes\n");
@@ -680,6 +708,12 @@ wsOpen(InputInfoPtr pInfo)
static void
wsClose(InputInfoPtr pInfo)
{
+ WSDevicePtr priv = (WSDevicePtr)pInfo->private;
+
+ if (priv->remove_timer != NULL) {
+ TimerFree(priv->remove_timer);
+ priv->remove_timer = NULL;
+ }
xf86CloseSerial(pInfo->fd);
pInfo->fd = -1;
}
Index: driver/xf86-input-ws/src/ws.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-input-ws/src/ws.h,v
retrieving revision 1.14
diff -u -p -r1.14 ws.h
--- driver/xf86-input-ws/src/ws.h 29 Aug 2015 08:48:29 -0000 1.14
+++ driver/xf86-input-ws/src/ws.h 16 Oct 2016 23:47:01 -0000
@@ -87,6 +87,8 @@ typedef struct WSDevice {
Time timeout;
} emulateWheel;
+ OsTimerPtr remove_timer; /* Callback for removal on EIO */
+
struct wscons_event events[NWSEVENTS];
size_t events_count;
size_t events_pos;