include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / input / serio / libps2.c
index ed202f2..980af94 100644 (file)
 
 #include <linux/delay.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/serio.h>
+#include <linux/i8042.h>
 #include <linux/init.h>
 #include <linux/libps2.h>
 
@@ -27,24 +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;
-       struct ps2dev *ps2dev;
-       int command;
-       unsigned char param[0];
-};
-
-
 /*
  * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
  * It doesn't handle retransmission, though it could - because if there
@@ -71,6 +53,25 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
 
        return -ps2dev->nak;
 }
+EXPORT_SYMBOL(ps2_sendbyte);
+
+void ps2_begin_command(struct ps2dev *ps2dev)
+{
+       mutex_lock(&ps2dev->cmd_mutex);
+
+       if (i8042_check_port_owner(ps2dev->serio))
+               i8042_lock_chip();
+}
+EXPORT_SYMBOL(ps2_begin_command);
+
+void ps2_end_command(struct ps2dev *ps2dev)
+{
+       if (i8042_check_port_owner(ps2dev->serio))
+               i8042_unlock_chip();
+
+       mutex_unlock(&ps2dev->cmd_mutex);
+}
+EXPORT_SYMBOL(ps2_end_command);
 
 /*
  * ps2_drain() waits for device to transmit requested number of bytes
@@ -84,7 +85,7 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
                maxbytes = sizeof(ps2dev->cmdbuf);
        }
 
-       mutex_lock(&ps2dev->cmd_mutex);
+       ps2_begin_command(ps2dev);
 
        serio_pause_rx(ps2dev->serio);
        ps2dev->flags = PS2_FLAG_CMD;
@@ -94,17 +95,19 @@ void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
        wait_event_timeout(ps2dev->wait,
                           !(ps2dev->flags & PS2_FLAG_CMD),
                           msecs_to_jiffies(timeout));
-       mutex_unlock(&ps2dev->cmd_mutex);
+
+       ps2_end_command(ps2dev);
 }
+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[] = {
+       static const char keyboard_ids[] = {
                0xab,   /* Regular keyboards            */
                0xac,   /* NCD Sun keyboard             */
                0x2b,   /* Trust keyboard, translated   */
@@ -115,6 +118,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 +143,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.
                         */
@@ -164,7 +181,7 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
  * ps2_command() can only be called from a process context
  */
 
-int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 {
        int timeout;
        int send = (command >> 12) & 0xf;
@@ -182,8 +199,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
                return -1;
        }
 
-       mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING);
-
        serio_pause_rx(ps2dev->serio);
        ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
        ps2dev->cmdcnt = receive;
@@ -213,7 +228,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
        timeout = wait_event_timeout(ps2dev->wait,
                                     !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
 
-       if (ps2dev->cmdcnt && timeout > 0) {
+       if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
 
                timeout = ps2_adjust_timeout(ps2dev, command, timeout);
                wait_event_timeout(ps2dev->wait,
@@ -234,51 +249,21 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
        ps2dev->flags = 0;
        serio_continue_rx(ps2dev->serio);
 
-       mutex_unlock(&ps2dev->cmd_mutex);
        return rc;
 }
+EXPORT_SYMBOL(__ps2_command);
 
-/*
- * ps2_execute_scheduled_command() sends a command, previously scheduled by
- * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.)
- */
-
-static void ps2_execute_scheduled_command(void *data)
-{
-       struct ps2work *ps2work = data;
-
-       ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command);
-       kfree(ps2work);
-}
-
-/*
- * ps2_schedule_command() allows to schedule delayed execution of a PS/2
- * command and can be used to issue a command from an interrupt or softirq
- * context.
- */
-
-int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 {
-       struct ps2work *ps2work;
-       int send = (command >> 12) & 0xf;
-       int receive = (command >> 8) & 0xf;
-
-       if (!(ps2work = kmalloc(sizeof(struct ps2work) + max(send, receive), GFP_ATOMIC)))
-               return -1;
+       int rc;
 
-       memset(ps2work, 0, sizeof(struct ps2work));
-       ps2work->ps2dev = ps2dev;
-       ps2work->command = command;
-       memcpy(ps2work->param, param, send);
-       INIT_WORK(&ps2work->work, ps2_execute_scheduled_command, ps2work);
+       ps2_begin_command(ps2dev);
+       rc = __ps2_command(ps2dev, param, command);
+       ps2_end_command(ps2dev);
 
-       if (!schedule_work(&ps2work->work)) {
-               kfree(ps2work);
-               return -1;
-       }
-
-       return 0;
+       return rc;
 }
+EXPORT_SYMBOL(ps2_command);
 
 /*
  * ps2_init() initializes ps2dev structure
@@ -287,9 +272,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
@@ -304,9 +291,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.
@@ -324,8 +319,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);
@@ -335,6 +333,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 +359,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)
 {
@@ -369,6 +369,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);