X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Finput%2Fserio%2Flibps2.c;h=e5b1b60757bb8d7a965aa92a87ffbae2e0264042;hb=acbb67d51ef0ff942d592d44fb8abb4c931041ff;hp=79c97f94bcbd5e9bcc31168020c3b7f1f0c32106;hpb=1810b6cb162e0c19e0ecbbacbcfd66f578f335ec;p=powerpc.git diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 79c97f94bc..e5b1b60757 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -27,15 +27,6 @@ MODULE_AUTHOR("Dmitry Torokhov "); 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 @@ -138,6 +132,19 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout) break; 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. @@ -177,6 +184,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) return -1; } + if (send && !param) { + WARN_ON(1); + return -1; + } + mutex_lock(&ps2dev->cmd_mutex); serio_pause_rx(ps2dev->serio); @@ -232,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 @@ -274,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 @@ -282,9 +296,11 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman void ps2_init(struct ps2dev *ps2dev, struct serio *serio) { mutex_init(&ps2dev->cmd_mutex); + lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); init_waitqueue_head(&ps2dev->wait); ps2dev->serio = serio; } +EXPORT_SYMBOL(ps2_init); /* * ps2_handle_ack() is supposed to be used in interrupt handler @@ -330,6 +346,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 @@ -355,6 +372,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) { @@ -366,4 +384,4 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev) ps2dev->flags = 0; } - +EXPORT_SYMBOL(ps2_cmd_aborted);