Input: psmouse - ignore parity error for basic protocols
Observing behavior of the other OS it appears that parity errors reported by the keyboard controller are being ignored and the data is processed as usual. Let's do the same for standard PS/2 protocols (bare, Intellimouse and Intellimouse Explorer) to provide better compatibility. Thsi should fix teh following bug: https://bugzilla.kernel.org/show_bug.cgi?id=6105 Thanks for Damjan Jovanovic for locating the source of issue and ideas for the patch. Tested-by: Damjan Jovanovic <damjan.jov@gmail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
parent
014f61504a
commit
6b9d363c49
drivers/input/mouse
@ -110,6 +110,7 @@ static struct workqueue_struct *kpsmoused_wq;
|
||||
struct psmouse_protocol {
|
||||
enum psmouse_type type;
|
||||
bool maxproto;
|
||||
bool ignore_parity; /* Protocol should ignore parity errors from KBC */
|
||||
const char *name;
|
||||
const char *alias;
|
||||
int (*detect)(struct psmouse *, bool);
|
||||
@ -288,7 +289,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
|
||||
if (psmouse->state == PSMOUSE_IGNORE)
|
||||
goto out;
|
||||
|
||||
if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) {
|
||||
if (unlikely((flags & SERIO_TIMEOUT) ||
|
||||
((flags & SERIO_PARITY) && !psmouse->ignore_parity))) {
|
||||
|
||||
if (psmouse->state == PSMOUSE_ACTIVATED)
|
||||
printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
|
||||
flags & SERIO_TIMEOUT ? " timeout" : "",
|
||||
@ -759,6 +762,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
|
||||
.name = "PS/2",
|
||||
.alias = "bare",
|
||||
.maxproto = true,
|
||||
.ignore_parity = true,
|
||||
.detect = ps2bare_detect,
|
||||
},
|
||||
#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
|
||||
@ -786,6 +790,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
|
||||
.name = "ImPS/2",
|
||||
.alias = "imps",
|
||||
.maxproto = true,
|
||||
.ignore_parity = true,
|
||||
.detect = intellimouse_detect,
|
||||
},
|
||||
{
|
||||
@ -793,6 +798,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
|
||||
.name = "ImExPS/2",
|
||||
.alias = "exps",
|
||||
.maxproto = true,
|
||||
.ignore_parity = true,
|
||||
.detect = im_explorer_detect,
|
||||
},
|
||||
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
|
||||
@ -1222,6 +1228,7 @@ static void psmouse_disconnect(struct serio *serio)
|
||||
static int psmouse_switch_protocol(struct psmouse *psmouse,
|
||||
const struct psmouse_protocol *proto)
|
||||
{
|
||||
const struct psmouse_protocol *selected_proto;
|
||||
struct input_dev *input_dev = psmouse->dev;
|
||||
|
||||
input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
|
||||
@ -1245,9 +1252,14 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
|
||||
return -1;
|
||||
|
||||
psmouse->type = proto->type;
|
||||
} else
|
||||
selected_proto = proto;
|
||||
} else {
|
||||
psmouse->type = psmouse_extensions(psmouse,
|
||||
psmouse_max_proto, true);
|
||||
selected_proto = psmouse_protocol_by_type(psmouse->type);
|
||||
}
|
||||
|
||||
psmouse->ignore_parity = selected_proto->ignore_parity;
|
||||
|
||||
/*
|
||||
* If mouse's packet size is 3 there is no point in polling the
|
||||
@ -1267,7 +1279,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
|
||||
psmouse->resync_time = 0;
|
||||
|
||||
snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s",
|
||||
psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
|
||||
selected_proto->name, psmouse->vendor, psmouse->name);
|
||||
|
||||
input_dev->name = psmouse->devname;
|
||||
input_dev->phys = psmouse->phys;
|
||||
|
@ -47,6 +47,7 @@ struct psmouse {
|
||||
unsigned char pktcnt;
|
||||
unsigned char pktsize;
|
||||
unsigned char type;
|
||||
bool ignore_parity;
|
||||
bool acks_disable_command;
|
||||
unsigned int model;
|
||||
unsigned long last;
|
||||
|
Loading…
Reference in New Issue
Block a user