2010-03-29 22:28:20 |
Jerone Young |
description |
I'm working on an OEM laptop where on boot the touchpad works just fine, but
after coming back from S3, the system doesn't detect that a touchpad is present.
I instrumented the psmouse driver and later the libps2 core and found we were
bailing in psmouse_probe with -ENODEV.
[ 2241.043143] XXX loading psmouse module
[ 2241.043321] XXX finished loading psmouse [0]
[ 2241.043614] XXX (psmouse_connect) ENTER
[ 2241.043622] XXX (psmouse_probe) ENTER:879
[ 2241.043626] XXX (psmouse_probe) HERE [/root/build/linux-2.6.31/drivers/input/mouse/psmouse-base.c:887]
[ 2241.240721] XXX (psmouse_connect) psmouse probe failed ENODEV
printk(KERN_INFO "XXX (%s) HERE [%s:%d] \n", __FUNCTION__, __FILE__, __LINE__);
param[0] = 0xa5;
if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
return -1;
and...
Here's what's going on in libps2 during the failed probe which results in -ENODEV
0 kseriod(41): -> ps2_init
ps2_init args [ps2dev=0xf006de08 serio=0xf6d36200 ]
exit 17 kseriod(41): -> ps2_init
ps2_init args []
0 kseriod(41): -> ps2_command
ps2_command args [ps2dev=0xf006de08 param=0xf75bbeaa command=0x2f2 ]
(ps2_command) libps2.c:172
(ps2_command) libps2.c:177
(ps2_command) libps2.c:182
(ps2_command) libps2.c:197
42 kseriod(41): -> ps2_sendbyte
ps2_sendbyte args [ps2dev=0xf006de08 byte=0xf2 timeout=0xc8 ]
exit 200048 kseriod(41): -> ps2_sendbyte
ps2_sendbyte args [return=0xffffffffffffffff ]
(ps2_command) libps2.c:224
exit 200070 kseriod(41): -> ps2_command
ps2_command args [return=0xffffffffffffffff ]
Generated by systemtap
...
probe kernel.function("ps2_*").call {
printf ("%s -> %s\n", thread_indent(1), probefunc())
printf ("%s args [%s]\n", probefunc(), $$parms)
}
probe kernel.function("ps2_*").return {
printf ("exit %s -> %s\n", thread_indent(-1), probefunc())
printf ("%s args [%s]\n", probefunc(), $$return)
}
So I noticed that while we have some elaborate reset code once we know what
kind of ps2 device we have, the probe routine itself by comparison doesn't try
as hard. The attached patch perfoms a psmouse_reset on the port should the
initial probe fail followed by a therapeutic 1/2 sec sleep. The attach patch
does exactly that and retries that probe up to 3 times. I only need one reset
to recover the Synaptic touchpad.
This is still broken in lucid as of the 3/27 build. |
Upcoming Dell Laptop being worked on by OEM has a touchpad that works fine on boot, but
after coming back from S3 suspend, the system doesn't detect that a touchpad is present.
The kernel psmouse driver was instrumented and later the libps2 core and found we were
bailing in psmouse_probe with -ENODEV.
[ 2241.043143] XXX loading psmouse module
[ 2241.043321] XXX finished loading psmouse [0]
[ 2241.043614] XXX (psmouse_connect) ENTER
[ 2241.043622] XXX (psmouse_probe) ENTER:879
[ 2241.043626] XXX (psmouse_probe) HERE [/root/build/linux-2.6.31/drivers/input/mouse/psmouse-base.c:887]
[ 2241.240721] XXX (psmouse_connect) psmouse probe failed ENODEV
printk(KERN_INFO "XXX (%s) HERE [%s:%d] \n", __FUNCTION__, __FILE__, __LINE__);
param[0] = 0xa5;
if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
return -1;
and...
Here's what's going on in libps2 during the failed probe which results in -ENODEV
0 kseriod(41): -> ps2_init
ps2_init args [ps2dev=0xf006de08 serio=0xf6d36200 ]
exit 17 kseriod(41): -> ps2_init
ps2_init args []
0 kseriod(41): -> ps2_command
ps2_command args [ps2dev=0xf006de08 param=0xf75bbeaa command=0x2f2 ]
(ps2_command) libps2.c:172
(ps2_command) libps2.c:177
(ps2_command) libps2.c:182
(ps2_command) libps2.c:197
42 kseriod(41): -> ps2_sendbyte
ps2_sendbyte args [ps2dev=0xf006de08 byte=0xf2 timeout=0xc8 ]
exit 200048 kseriod(41): -> ps2_sendbyte
ps2_sendbyte args [return=0xffffffffffffffff ]
(ps2_command) libps2.c:224
exit 200070 kseriod(41): -> ps2_command
ps2_command args [return=0xffffffffffffffff ]
Generated by systemtap
...
probe kernel.function("ps2_*").call {
printf ("%s -> %s\n", thread_indent(1), probefunc())
printf ("%s args [%s]\n", probefunc(), $$parms)
}
probe kernel.function("ps2_*").return {
printf ("exit %s -> %s\n", thread_indent(-1), probefunc())
printf ("%s args [%s]\n", probefunc(), $$return)
}
So I noticed that while we have some elaborate reset code once we know what
kind of ps2 device we have, the probe routine itself by comparison doesn't try
as hard.
The attached patch perfoms a psmouse_reset on the port should the
initial probe fail followed by a therapeutic 1/2 sec sleep. The attach patch
does exactly that and retries that probe up to 3 times. I only need one reset
to recover the Synaptic touchpad.
|
|