On 29 July 2013 12:31, Mark Kettenis <[email protected]> wrote: >> 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.
Says who? nightslugs:~/x/xorg/xserver(master)% g -r '^_' **/*.[ch] | grep -v _X_ | wc -l 1857 >> 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
