Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial
[pandora-kernel.git] / drivers / input / serio / libps2.c
index 61a6f97..dcb16b5 100644 (file)
@@ -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
@@ -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_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING);
 
        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
@@ -285,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
@@ -330,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
@@ -355,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)
 {
@@ -366,4 +383,4 @@ void ps2_cmd_aborted(struct ps2dev *ps2dev)
 
        ps2dev->flags = 0;
 }
-
+EXPORT_SYMBOL(ps2_cmd_aborted);