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;

Reply via email to