diff options
Diffstat (limited to 'drivers/input/serio/libps2.c')
-rw-r--r-- | drivers/input/serio/libps2.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index ed202f2f251..dcb16b5cbec 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -27,15 +27,6 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); MODULE_DESCRIPTION("PS/2 driver library"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(ps2_init); -EXPORT_SYMBOL(ps2_sendbyte); -EXPORT_SYMBOL(ps2_drain); -EXPORT_SYMBOL(ps2_command); -EXPORT_SYMBOL(ps2_schedule_command); -EXPORT_SYMBOL(ps2_handle_ack); -EXPORT_SYMBOL(ps2_handle_response); -EXPORT_SYMBOL(ps2_cmd_aborted); - /* Work structure to schedule execution of a command */ struct ps2work { struct work_struct work; @@ -71,6 +62,7 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) return -ps2dev->nak; } +EXPORT_SYMBOL(ps2_sendbyte); /* * ps2_drain() waits for device to transmit requested number of bytes @@ -96,15 +88,16 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) msecs_to_jiffies(timeout)); mutex_unlock(&ps2dev->cmd_mutex); } +EXPORT_SYMBOL(ps2_drain); /* * ps2_is_keyboard_id() checks received ID byte against the list of * 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 */ @@ -115,6 +108,7 @@ static inline int ps2_is_keyboard_id(char id_byte) return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL; } +EXPORT_SYMBOL(ps2_is_keyboard_id); /* * ps2_adjust_timeout() is called after receiving 1st byte of command @@ -139,6 +133,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. */ @@ -237,6 +244,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) mutex_unlock(&ps2dev->cmd_mutex); return rc; } +EXPORT_SYMBOL(ps2_command); /* * ps2_execute_scheduled_command() sends a command, previously scheduled by @@ -279,6 +287,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman return 0; } +EXPORT_SYMBOL(ps2_schedule_command); /* * ps2_init() initializes ps2dev structure @@ -290,6 +299,7 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio) init_waitqueue_head(&ps2dev->wait); ps2dev->serio = serio; } +EXPORT_SYMBOL(ps2_init); /* * ps2_handle_ack() is supposed to be used in interrupt handler @@ -335,6 +345,7 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data) return 1; } +EXPORT_SYMBOL(ps2_handle_ack); /* * ps2_handle_response() is supposed to be used in interrupt handler @@ -360,6 +371,7 @@ int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data) return 1; } +EXPORT_SYMBOL(ps2_handle_response); void ps2_cmd_aborted(struct ps2dev *ps2dev) { @@ -371,4 +383,4 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev) ps2dev->flags = 0; } - +EXPORT_SYMBOL(ps2_cmd_aborted); |