Input: libps2 - handle 0xfc responses from devices
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 19 Nov 2008 22:02:24 +0000 (17:02 -0500)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 24 Nov 2008 16:43:21 +0000 (11:43 -0500)
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/input/serio/libps2.c
include/linux/libps2.h

index 2b304c2..67248c3 100644 (file)
@@ -262,9 +262,17 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
                        break;
 
                case PS2_RET_NAK:
-                       ps2dev->nak = 1;
+                       ps2dev->flags |= PS2_FLAG_NAK;
+                       ps2dev->nak = PS2_RET_NAK;
                        break;
 
+               case PS2_RET_ERR:
+                       if (ps2dev->flags & PS2_FLAG_NAK) {
+                               ps2dev->flags &= ~PS2_FLAG_NAK;
+                               ps2dev->nak = PS2_RET_ERR;
+                               break;
+                       }
+
                /*
                 * Workaround for mice which don't ACK the Get ID command.
                 * These are valid mouse IDs that we recognize.
@@ -282,8 +290,11 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
        }
 
 
-       if (!ps2dev->nak && ps2dev->cmdcnt)
-               ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
+       if (!ps2dev->nak) {
+               ps2dev->flags &= ~PS2_FLAG_NAK;
+               if (ps2dev->cmdcnt)
+                       ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
+       }
 
        ps2dev->flags &= ~PS2_FLAG_ACK;
        wake_up(&ps2dev->wait);
@@ -329,6 +340,7 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev)
        if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
                wake_up(&ps2dev->wait);
 
-       ps2dev->flags = 0;
+       /* reset all flags except last nack */
+       ps2dev->flags &= PS2_FLAG_NAK;
 }
 EXPORT_SYMBOL(ps2_cmd_aborted);
index afc4133..b94534b 100644 (file)
 #define PS2_RET_ID             0x00
 #define PS2_RET_ACK            0xfa
 #define PS2_RET_NAK            0xfe
+#define PS2_RET_ERR            0xfc
 
 #define PS2_FLAG_ACK           1       /* Waiting for ACK/NAK */
 #define PS2_FLAG_CMD           2       /* Waiting for command to finish */
 #define PS2_FLAG_CMD1          4       /* Waiting for the first byte of command response */
 #define PS2_FLAG_WAITID                8       /* Command execiting is GET ID */
+#define PS2_FLAG_NAK           16      /* Last transmission was NAKed */
 
 struct ps2dev {
        struct serio *serio;