diff options
Diffstat (limited to 'drivers/input/serio/libps2.c')
-rw-r--r-- | drivers/input/serio/libps2.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index c978657068c5..92b92ee03791 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL"); | |||
29 | 29 | ||
30 | EXPORT_SYMBOL(ps2_init); | 30 | EXPORT_SYMBOL(ps2_init); |
31 | EXPORT_SYMBOL(ps2_sendbyte); | 31 | EXPORT_SYMBOL(ps2_sendbyte); |
32 | EXPORT_SYMBOL(ps2_drain); | ||
32 | EXPORT_SYMBOL(ps2_command); | 33 | EXPORT_SYMBOL(ps2_command); |
33 | EXPORT_SYMBOL(ps2_schedule_command); | 34 | EXPORT_SYMBOL(ps2_schedule_command); |
34 | EXPORT_SYMBOL(ps2_handle_ack); | 35 | EXPORT_SYMBOL(ps2_handle_ack); |
@@ -45,11 +46,11 @@ struct ps2work { | |||
45 | 46 | ||
46 | 47 | ||
47 | /* | 48 | /* |
48 | * ps2_sendbyte() sends a byte to the mouse, and waits for acknowledge. | 49 | * ps2_sendbyte() sends a byte to the device and waits for acknowledge. |
49 | * It doesn't handle retransmission, though it could - because when there would | 50 | * It doesn't handle retransmission, though it could - because if there |
50 | * be need for retransmissions, the mouse has to be replaced anyway. | 51 | * is a need for retransmissions device has to be replaced anyway. |
51 | * | 52 | * |
52 | * ps2_sendbyte() can only be called from a process context | 53 | * ps2_sendbyte() can only be called from a process context. |
53 | */ | 54 | */ |
54 | 55 | ||
55 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) | 56 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) |
@@ -72,6 +73,31 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) | |||
72 | } | 73 | } |
73 | 74 | ||
74 | /* | 75 | /* |
76 | * ps2_drain() waits for device to transmit requested number of bytes | ||
77 | * and discards them. | ||
78 | */ | ||
79 | |||
80 | void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) | ||
81 | { | ||
82 | if (maxbytes > sizeof(ps2dev->cmdbuf)) { | ||
83 | WARN_ON(1); | ||
84 | maxbytes = sizeof(ps2dev->cmdbuf); | ||
85 | } | ||
86 | |||
87 | down(&ps2dev->cmd_sem); | ||
88 | |||
89 | serio_pause_rx(ps2dev->serio); | ||
90 | ps2dev->flags = PS2_FLAG_CMD; | ||
91 | ps2dev->cmdcnt = maxbytes; | ||
92 | serio_continue_rx(ps2dev->serio); | ||
93 | |||
94 | wait_event_timeout(ps2dev->wait, | ||
95 | !(ps2dev->flags & PS2_FLAG_CMD), | ||
96 | msecs_to_jiffies(timeout)); | ||
97 | up(&ps2dev->cmd_sem); | ||
98 | } | ||
99 | |||
100 | /* | ||
75 | * ps2_command() sends a command and its parameters to the mouse, | 101 | * ps2_command() sends a command and its parameters to the mouse, |
76 | * then waits for the response and puts it in the param array. | 102 | * then waits for the response and puts it in the param array. |
77 | * | 103 | * |
@@ -86,6 +112,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
86 | int rc = -1; | 112 | int rc = -1; |
87 | int i; | 113 | int i; |
88 | 114 | ||
115 | if (receive > sizeof(ps2dev->cmdbuf)) { | ||
116 | WARN_ON(1); | ||
117 | return -1; | ||
118 | } | ||
119 | |||
89 | down(&ps2dev->cmd_sem); | 120 | down(&ps2dev->cmd_sem); |
90 | 121 | ||
91 | serio_pause_rx(ps2dev->serio); | 122 | serio_pause_rx(ps2dev->serio); |
@@ -101,10 +132,9 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
101 | * ACKing the reset command, and so it can take a long | 132 | * ACKing the reset command, and so it can take a long |
102 | * time before the ACK arrrives. | 133 | * time before the ACK arrrives. |
103 | */ | 134 | */ |
104 | if (command & 0xff) | 135 | if (ps2_sendbyte(ps2dev, command & 0xff, |
105 | if (ps2_sendbyte(ps2dev, command & 0xff, | 136 | command == PS2_CMD_RESET_BAT ? 1000 : 200)) |
106 | command == PS2_CMD_RESET_BAT ? 1000 : 200)) | 137 | goto out; |
107 | goto out; | ||
108 | 138 | ||
109 | for (i = 0; i < send; i++) | 139 | for (i = 0; i < send; i++) |
110 | if (ps2_sendbyte(ps2dev, param[i], 200)) | 140 | if (ps2_sendbyte(ps2dev, param[i], 200)) |