On Mon 12.Oct'09 at 20:24:14 -0700, Dmitry Torokhov wrote: > Could you please try this patch and let me know if it helps. Yes! The patch quoted below fixed the problem. (and I tested it twice already, since I read your suggestion in the other thread :-) > Anotehr i8042.dmesg would be much appreciated. Sure, it is here: http://www.aei.mpg.de/~crmafra/syslog-i8042.debug-patched.txt > Input: psmouse - retry reset command if first one fails > > From: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx> > > Sometimes mice are not ready for a command and respond with 0xfe; > failure to reset mouse can lead to losing the device to let's try > harder and repeat the command after delay. > > Signed-off-by: Dmitry Torokhov <dtor@xxxxxxx> > --- > > drivers/input/mouse/psmouse-base.c | 13 ++++++++++++- > drivers/input/serio/libps2.c | 31 +++++++++++++++++-------------- > 2 files changed, 29 insertions(+), 15 deletions(-) > > > diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c > index 690aed9..52ad50f 100644 > --- a/drivers/input/mouse/psmouse-base.c > +++ b/drivers/input/mouse/psmouse-base.c > @@ -395,8 +395,19 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command) > int psmouse_reset(struct psmouse *psmouse) > { > unsigned char param[2]; > + int error; > + > + error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT); > + if (error == -EAGAIN) { > + /* > + * Controller requested us to resend the command. > + */ > + msleep(100); > + error = ps2_command(&psmouse->ps2dev, > + param, PSMOUSE_CMD_RESET_BAT); > + } > > - if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT)) > + if (error) > return -1; > > if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID) > diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c > index f3876ac..5201b0c 100644 > --- a/drivers/input/serio/libps2.c > +++ b/drivers/input/serio/libps2.c > @@ -39,7 +39,7 @@ MODULE_LICENSE("GPL"); > int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) > { > serio_pause_rx(ps2dev->serio); > - ps2dev->nak = 1; > + ps2dev->nak = ETIME; > ps2dev->flags |= PS2_FLAG_ACK; > serio_continue_rx(ps2dev->serio); > > @@ -187,17 +187,17 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) > int timeout; > int send = (command >> 12) & 0xf; > int receive = (command >> 8) & 0xf; > - int rc = -1; > + int rc; > int i; > > if (receive > sizeof(ps2dev->cmdbuf)) { > WARN_ON(1); > - return -1; > + return -EINVAL; > } > > if (send && !param) { > WARN_ON(1); > - return -1; > + return -EINVAL; > } > > serio_pause_rx(ps2dev->serio); > @@ -213,13 +213,16 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) > * ACKing the reset command, and so it can take a long > * time before the ACK arrrives. > */ > - if (ps2_sendbyte(ps2dev, command & 0xff, > - command == PS2_CMD_RESET_BAT ? 1000 : 200)) > + rc = ps2_sendbyte(ps2dev, command & 0xff, > + command == PS2_CMD_RESET_BAT ? 1000 : 200); > + if (rc) > goto out; > > - for (i = 0; i < send; i++) > - if (ps2_sendbyte(ps2dev, param[i], 200)) > + for (i = 0; i < send; i++) { > + rc = ps2_sendbyte(ps2dev, param[i], 200); > + if (rc) > goto out; > + } > > /* > * The reset command takes a long time to execute. > @@ -240,10 +243,10 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) > for (i = 0; i < receive; i++) > param[i] = ps2dev->cmdbuf[(receive - 1) - i]; > > - if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) > + if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) { > + rc = ETIME; > goto out; > - > - rc = 0; > + } > > out: > serio_pause_rx(ps2dev->serio); > @@ -293,13 +296,13 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data) > > case PS2_RET_NAK: > ps2dev->flags |= PS2_FLAG_NAK; > - ps2dev->nak = PS2_RET_NAK; > + ps2dev->nak = EAGAIN; > break; > > case PS2_RET_ERR: > if (ps2dev->flags & PS2_FLAG_NAK) { > ps2dev->flags &= ~PS2_FLAG_NAK; > - ps2dev->nak = PS2_RET_ERR; > + ps2dev->nak = EIO; > break; > } > > @@ -365,7 +368,7 @@ EXPORT_SYMBOL(ps2_handle_response); > void ps2_cmd_aborted(struct ps2dev *ps2dev) > { > if (ps2dev->flags & PS2_FLAG_ACK) > - ps2dev->nak = 1; > + ps2dev->nak = EIO; > > if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) > wake_up(&ps2dev->wait); -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html