> From: Egbert Eich <[email protected]> > Date: Mon, 29 Jul 2013 13:15:13 +0200 > > From: Takashi Iwai <[email protected]> > > Under some circumstances the synaptics device may be wedged when > coming back from a sleep state. Add some magic which tries to > detect this and reconnect.
You shouldn't use function names that start with an underscore. > Signed-off-by: Takashi Iwai <[email protected]> > Signed-off-by: Egbert Eich <[email protected]> > --- > src/eventcomm.c | 3 ++- > src/synaptics.c | 56 > +++++++++++++++++++++++++++++++++++++++++++++++------- > src/synapticsstr.h | 3 +++ > 3 files changed, 54 insertions(+), 8 deletions(-) > > diff --git a/src/eventcomm.c b/src/eventcomm.c > index 258a538..86b74cb 100644 > --- a/src/eventcomm.c > +++ b/src/eventcomm.c > @@ -638,7 +638,8 @@ EventReadHwState(InputInfoPtr pInfo, > } > > while (SynapticsReadEvent(pInfo, &ev)) { > - switch (ev.type) { > + priv->comm_read++; > + switch (ev.type) { > case EV_SYN: > switch (ev.code) { > case SYN_REPORT: > diff --git a/src/synaptics.c b/src/synaptics.c > index f0a8269..31e147c 100644 > --- a/src/synaptics.c > +++ b/src/synaptics.c > @@ -920,18 +920,30 @@ DeviceControl(DeviceIntPtr dev, int mode) > } > > static int > -DeviceOn(DeviceIntPtr dev) > +_DeviceOn(InputInfoPtr pInfo) > { > - InputInfoPtr pInfo = dev->public.devicePrivate; > SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private); > + int n; > > DBG(3, "Synaptics DeviceOn called\n"); > > - pInfo->fd = xf86OpenSerial(pInfo->options); > + for (n = priv->retries; n >= 0; n--) { > + pInfo->fd = xf86OpenSerial(pInfo->options); > + if (pInfo->fd != -1) > + break; > + if (n) > + xf86Msg(X_WARNING, "%s: cannot open input device - " > + "retrying %d more times\n", pInfo->name, n); > + } > if (pInfo->fd == -1) { > xf86IDrvMsg(pInfo, X_WARNING, "cannot open input device\n"); > return !Success; > } > + /* This has succeeded once, so chances are the hardware *really* is > present > + * - this is not a hotplug device after all. > + * Without trying really hard on some machines with some kernels the > device > + * won't be found after S3/S4 again. */ > + priv->retries = 4; > > if (priv->proto_ops->DeviceOnHook && > !priv->proto_ops->DeviceOnHook(pInfo, &priv->synpara)) > @@ -956,11 +968,21 @@ DeviceOn(DeviceIntPtr dev) > } > > xf86AddEnabledDevice(pInfo); > - dev->public.on = TRUE; > > return Success; > } > > +static int > +DeviceOn(DeviceIntPtr dev) > +{ > + int ret = _DeviceOn(dev->public.devicePrivate); > + > + if (ret == Success) > + dev->public.on = TRUE; > + > + return ret; > +} > + > static void > SynapticsReset(SynapticsPrivate * priv) > { > @@ -995,9 +1017,8 @@ SynapticsReset(SynapticsPrivate * priv) > } > > static int > -DeviceOff(DeviceIntPtr dev) > +_DeviceOff(InputInfoPtr pInfo) > { > - InputInfoPtr pInfo = dev->public.devicePrivate; > SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private); > Bool rc = Success; > > @@ -1018,11 +1039,18 @@ DeviceOff(DeviceIntPtr dev) > xf86CloseSerial(pInfo->fd); > pInfo->fd = -1; > } > - dev->public.on = FALSE; > return rc; > } > > static int > +DeviceOff(DeviceIntPtr dev) > +{ > + int ret = _DeviceOff(dev->public.devicePrivate); > + dev->public.on = FALSE; > + return ret; > +} > + > +static int > DeviceClose(DeviceIntPtr dev) > { > Bool RetValue; > @@ -1469,6 +1497,7 @@ ReadInput(InputInfoPtr pInfo) > > SynapticsResetTouchHwState(hw, FALSE); > > + priv->comm_read = 0; > while (SynapticsGetHwState(pInfo, priv, hw)) { > /* Semi-mt device touch slots do not track touches. When there is a > * change in the number of touches, we must disregard the temporary > @@ -1487,6 +1516,19 @@ ReadInput(InputInfoPtr pInfo) > newDelay = TRUE; > } > > + if (!priv->comm_read) { > + /* strange callback, check the device and reconnect if needed */ > + if (!priv->reconnecting) { > + priv->reconnecting = 1; > + xf86Msg(X_WARNING, "%s: reconnecting device...\n", pInfo->name); > + _DeviceOff(pInfo); > + usleep(100*1000); > + _DeviceOn(pInfo); > + xf86Msg(X_WARNING, "%s: reconnection done\n", pInfo->name); > + } else > + priv->reconnecting = 0; > + } > + > if (newDelay) { > priv->timer_time = GetTimeInMillis(); > priv->timer = TimerSet(priv->timer, 0, delay, timerFunc, pInfo); > diff --git a/src/synapticsstr.h b/src/synapticsstr.h > index 428befa..98d6552 100644 > --- a/src/synapticsstr.h > +++ b/src/synapticsstr.h > @@ -204,6 +204,9 @@ struct _SynapticsPrivateRec { > OsTimerPtr timer; /* for tap processing, etc */ > > struct CommData comm; > + int comm_read; /* for reconnection check */ > + int reconnecting; /* for reconnection check */ > + int retries; > > struct SynapticsHwState *local_hw_state; /* used in place of local hw > state variables */ > > -- > 1.8.1.4 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel > _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
