aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/mouse/alps.c3
-rw-r--r--drivers/input/serio/libps2.c46
-rw-r--r--include/linux/libps2.h1
3 files changed, 40 insertions, 10 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 2679a165d399..ffdc82313192 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -270,7 +270,6 @@ static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *vers
270static int alps_passthrough_mode(struct psmouse *psmouse, int enable) 270static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
271{ 271{
272 struct ps2dev *ps2dev = &psmouse->ps2dev; 272 struct ps2dev *ps2dev = &psmouse->ps2dev;
273 unsigned char param[3];
274 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; 273 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
275 274
276 if (ps2_command(ps2dev, NULL, cmd) || 275 if (ps2_command(ps2dev, NULL, cmd) ||
@@ -280,7 +279,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
280 return -1; 279 return -1;
281 280
282 /* we may get 3 more bytes, just ignore them */ 281 /* we may get 3 more bytes, just ignore them */
283 ps2_command(ps2dev, param, 0x0300); 282 ps2_drain(ps2dev, 3, 100);
284 283
285 return 0; 284 return 0;
286} 285}
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
30EXPORT_SYMBOL(ps2_init); 30EXPORT_SYMBOL(ps2_init);
31EXPORT_SYMBOL(ps2_sendbyte); 31EXPORT_SYMBOL(ps2_sendbyte);
32EXPORT_SYMBOL(ps2_drain);
32EXPORT_SYMBOL(ps2_command); 33EXPORT_SYMBOL(ps2_command);
33EXPORT_SYMBOL(ps2_schedule_command); 34EXPORT_SYMBOL(ps2_schedule_command);
34EXPORT_SYMBOL(ps2_handle_ack); 35EXPORT_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
55int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) 56int 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
80void 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))
diff --git a/include/linux/libps2.h b/include/linux/libps2.h
index 923bdbc6d9e4..a710bddda4eb 100644
--- a/include/linux/libps2.h
+++ b/include/linux/libps2.h
@@ -41,6 +41,7 @@ struct ps2dev {
41 41
42void ps2_init(struct ps2dev *ps2dev, struct serio *serio); 42void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
43int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); 43int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
44void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
44int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); 45int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
45int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command); 46int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command);
46int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); 47int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);