diff options
-rw-r--r-- | drivers/input/mouse/alps.c | 3 | ||||
-rw-r--r-- | drivers/input/serio/libps2.c | 46 | ||||
-rw-r--r-- | include/linux/libps2.h | 1 |
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 | |||
270 | static int alps_passthrough_mode(struct psmouse *psmouse, int enable) | 270 | static 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 | ||
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)) |
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 | ||
42 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio); | 42 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio); |
43 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); | 43 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); |
44 | void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout); | ||
44 | int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); | 45 | int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); |
45 | int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command); | 46 | int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command); |
46 | int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); | 47 | int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); |