Commit c611763d authored by Dmitry Torokhov's avatar Dmitry Torokhov

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: default avatarDmitry Torokhov <dtor@mail.ru>
parent 04df1925
...@@ -270,7 +270,6 @@ static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *vers ...@@ -270,7 +270,6 @@ static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *vers
static int alps_passthrough_mode(struct psmouse *psmouse, int enable) static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
{ {
struct ps2dev *ps2dev = &psmouse->ps2dev; struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[3];
int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
if (ps2_command(ps2dev, NULL, cmd) || if (ps2_command(ps2dev, NULL, cmd) ||
...@@ -280,7 +279,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, int enable) ...@@ -280,7 +279,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
return -1; return -1;
/* we may get 3 more bytes, just ignore them */ /* we may get 3 more bytes, just ignore them */
ps2_command(ps2dev, param, 0x0300); ps2_drain(ps2dev, 3, 100);
return 0; return 0;
} }
......
...@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL"); ...@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
EXPORT_SYMBOL(ps2_init); EXPORT_SYMBOL(ps2_init);
EXPORT_SYMBOL(ps2_sendbyte); EXPORT_SYMBOL(ps2_sendbyte);
EXPORT_SYMBOL(ps2_drain);
EXPORT_SYMBOL(ps2_command); EXPORT_SYMBOL(ps2_command);
EXPORT_SYMBOL(ps2_schedule_command); EXPORT_SYMBOL(ps2_schedule_command);
EXPORT_SYMBOL(ps2_handle_ack); EXPORT_SYMBOL(ps2_handle_ack);
...@@ -45,11 +46,11 @@ struct ps2work { ...@@ -45,11 +46,11 @@ struct ps2work {
/* /*
* ps2_sendbyte() sends a byte to the mouse, and waits for acknowledge. * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
* It doesn't handle retransmission, though it could - because when there would * It doesn't handle retransmission, though it could - because if there
* be need for retransmissions, the mouse has to be replaced anyway. * is a need for retransmissions device has to be replaced anyway.
* *
* ps2_sendbyte() can only be called from a process context * ps2_sendbyte() can only be called from a process context.
*/ */
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
...@@ -71,6 +72,31 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) ...@@ -71,6 +72,31 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
return -ps2dev->nak; return -ps2dev->nak;
} }
/*
* ps2_drain() waits for device to transmit requested number of bytes
* and discards them.
*/
void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
{
if (maxbytes > sizeof(ps2dev->cmdbuf)) {
WARN_ON(1);
maxbytes = sizeof(ps2dev->cmdbuf);
}
down(&ps2dev->cmd_sem);
serio_pause_rx(ps2dev->serio);
ps2dev->flags = PS2_FLAG_CMD;
ps2dev->cmdcnt = maxbytes;
serio_continue_rx(ps2dev->serio);
wait_event_timeout(ps2dev->wait,
!(ps2dev->flags & PS2_FLAG_CMD),
msecs_to_jiffies(timeout));
up(&ps2dev->cmd_sem);
}
/* /*
* ps2_command() sends a command and its parameters to the mouse, * ps2_command() sends a command and its parameters to the mouse,
* then waits for the response and puts it in the param array. * then waits for the response and puts it in the param array.
...@@ -86,6 +112,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) ...@@ -86,6 +112,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
int rc = -1; int rc = -1;
int i; int i;
if (receive > sizeof(ps2dev->cmdbuf)) {
WARN_ON(1);
return -1;
}
down(&ps2dev->cmd_sem); down(&ps2dev->cmd_sem);
serio_pause_rx(ps2dev->serio); serio_pause_rx(ps2dev->serio);
...@@ -101,7 +132,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) ...@@ -101,7 +132,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
* ACKing the reset command, and so it can take a long * ACKing the reset command, and so it can take a long
* time before the ACK arrrives. * time before the ACK arrrives.
*/ */
if (command & 0xff)
if (ps2_sendbyte(ps2dev, command & 0xff, if (ps2_sendbyte(ps2dev, command & 0xff,
command == PS2_CMD_RESET_BAT ? 1000 : 200)) command == PS2_CMD_RESET_BAT ? 1000 : 200))
goto out; goto out;
......
...@@ -41,6 +41,7 @@ struct ps2dev { ...@@ -41,6 +41,7 @@ struct ps2dev {
void ps2_init(struct ps2dev *ps2dev, struct serio *serio); void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command); int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment