diff options
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 4 | ||||
-rw-r--r-- | drivers/input/serio/libps2.c | 18 | ||||
-rw-r--r-- | include/linux/libps2.h | 1 |
3 files changed, 18 insertions, 5 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ce1f10e8984..9874072cf9d 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -635,9 +635,7 @@ static int atkbd_probe(struct atkbd *atkbd) return 0; } - if (param[0] != 0xab && param[0] != 0xac && /* Regular and NCD Sun keyboards */ - param[0] != 0x2b && param[0] != 0x5d && /* Trust keyboard, raw and translated */ - param[0] != 0x60 && param[0] != 0x47) /* NMB SGI keyboard, raw and translated */ + if (!ps2_is_keyboard_id(param[0])) return -1; atkbd->id = (param[0] << 8) | param[1]; diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index ed202f2f251..e0a2297a9d2 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -35,6 +35,7 @@ EXPORT_SYMBOL(ps2_schedule_command); EXPORT_SYMBOL(ps2_handle_ack); EXPORT_SYMBOL(ps2_handle_response); EXPORT_SYMBOL(ps2_cmd_aborted); +EXPORT_SYMBOL(ps2_is_keyboard_id); /* Work structure to schedule execution of a command */ struct ps2work { @@ -102,9 +103,9 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) * known keyboard IDs. */ -static inline int ps2_is_keyboard_id(char id_byte) +int ps2_is_keyboard_id(char id_byte) { - static char keyboard_ids[] = { + const static char keyboard_ids[] = { 0xab, /* Regular keyboards */ 0xac, /* NCD Sun keyboard */ 0x2b, /* Trust keyboard, translated */ @@ -139,6 +140,19 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout) case PS2_CMD_GETID: /* + * Microsoft Natural Elite keyboard responds to + * the GET ID command as it were a mouse, with + * a single byte. Fail the command so atkbd will + * use alternative probe to detect it. + */ + if (ps2dev->cmdbuf[1] == 0xaa) { + serio_pause_rx(ps2dev->serio); + ps2dev->flags = 0; + serio_continue_rx(ps2dev->serio); + timeout = 0; + } + + /* * If device behind the port is not a keyboard there * won't be 2nd byte of ID response. */ diff --git a/include/linux/libps2.h b/include/linux/libps2.h index 08a450a9dbf..f6f301e2b0f 100644 --- a/include/linux/libps2.h +++ b/include/linux/libps2.h @@ -47,5 +47,6 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data); void ps2_cmd_aborted(struct ps2dev *ps2dev); +int ps2_is_keyboard_id(char id); #endif /* _LIBPS2_H */ |