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;