Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: add ps2_drain() to libps2 to allow reading and discarding given number of bytes from device. Change ps2_command to allow using 0 as command ID and actually pass it to the device instead of working as a drain.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

+40 -10
+1 -2
drivers/input/mouse/alps.c
··· 270 270 static int alps_passthrough_mode(struct psmouse *psmouse, int enable) 271 271 { 272 272 struct ps2dev *ps2dev = &psmouse->ps2dev; 273 - unsigned char param[3]; 274 273 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; 275 274 276 275 if (ps2_command(ps2dev, NULL, cmd) || ··· 279 280 return -1; 280 281 281 282 /* we may get 3 more bytes, just ignore them */ 282 - ps2_command(ps2dev, param, 0x0300); 283 + ps2_drain(ps2dev, 3, 100); 283 284 284 285 return 0; 285 286 }
+38 -8
drivers/input/serio/libps2.c
··· 29 29 30 30 EXPORT_SYMBOL(ps2_init); 31 31 EXPORT_SYMBOL(ps2_sendbyte); 32 + EXPORT_SYMBOL(ps2_drain); 32 33 EXPORT_SYMBOL(ps2_command); 33 34 EXPORT_SYMBOL(ps2_schedule_command); 34 35 EXPORT_SYMBOL(ps2_handle_ack); ··· 46 45 47 46 48 47 /* 49 - * ps2_sendbyte() sends a byte to the mouse, and waits for acknowledge. 50 - * It doesn't handle retransmission, though it could - because when there would 51 - * be need for retransmissions, the mouse has to be replaced anyway. 48 + * ps2_sendbyte() sends a byte to the device and waits for acknowledge. 49 + * It doesn't handle retransmission, though it could - because if there 50 + * is a need for retransmissions device has to be replaced anyway. 52 51 * 53 - * ps2_sendbyte() can only be called from a process context 52 + * ps2_sendbyte() can only be called from a process context. 54 53 */ 55 54 56 55 int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) ··· 73 72 } 74 73 75 74 /* 75 + * ps2_drain() waits for device to transmit requested number of bytes 76 + * and discards them. 77 + */ 78 + 79 + void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) 80 + { 81 + if (maxbytes > sizeof(ps2dev->cmdbuf)) { 82 + WARN_ON(1); 83 + maxbytes = sizeof(ps2dev->cmdbuf); 84 + } 85 + 86 + down(&ps2dev->cmd_sem); 87 + 88 + serio_pause_rx(ps2dev->serio); 89 + ps2dev->flags = PS2_FLAG_CMD; 90 + ps2dev->cmdcnt = maxbytes; 91 + serio_continue_rx(ps2dev->serio); 92 + 93 + wait_event_timeout(ps2dev->wait, 94 + !(ps2dev->flags & PS2_FLAG_CMD), 95 + msecs_to_jiffies(timeout)); 96 + up(&ps2dev->cmd_sem); 97 + } 98 + 99 + /* 76 100 * ps2_command() sends a command and its parameters to the mouse, 77 101 * then waits for the response and puts it in the param array. 78 102 * ··· 111 85 int receive = (command >> 8) & 0xf; 112 86 int rc = -1; 113 87 int i; 88 + 89 + if (receive > sizeof(ps2dev->cmdbuf)) { 90 + WARN_ON(1); 91 + return -1; 92 + } 114 93 115 94 down(&ps2dev->cmd_sem); 116 95 ··· 132 101 * ACKing the reset command, and so it can take a long 133 102 * time before the ACK arrrives. 134 103 */ 135 - if (command & 0xff) 136 - if (ps2_sendbyte(ps2dev, command & 0xff, 137 - command == PS2_CMD_RESET_BAT ? 1000 : 200)) 138 - goto out; 104 + if (ps2_sendbyte(ps2dev, command & 0xff, 105 + command == PS2_CMD_RESET_BAT ? 1000 : 200)) 106 + goto out; 139 107 140 108 for (i = 0; i < send; i++) 141 109 if (ps2_sendbyte(ps2dev, param[i], 200))
+1
include/linux/libps2.h
··· 41 41 42 42 void ps2_init(struct ps2dev *ps2dev, struct serio *serio); 43 43 int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); 44 + void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout); 44 45 int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); 45 46 int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command); 46 47 int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);