diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 7490f1d..82b34b6 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -378,10 +378,16 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) struct alps_data *priv = psmouse->private; const struct alps_model_info *model = priv->i; + if (psmouse->pktcnt == 1 && psmouse->badparity) + return PSMOUSE_BAD_DATA; + if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ if (psmouse->pktcnt == 3) { - alps_report_bare_ps2_packet(psmouse, psmouse->packet, - true); + if (psmouse->badparity) { + alps_report_bare_ps2_packet(psmouse, + psmouse->packet, + true); + } return PSMOUSE_FULL_PACKET; } return PSMOUSE_GOOD_DATA; @@ -391,6 +397,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) if ((model->flags & ALPS_PS2_INTERLEAVED) && psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) { + if (psmouse->badparity) + return PSMOUSE_BAD_DATA; return alps_handle_interleaved_ps2(psmouse); } @@ -409,7 +417,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) } if (psmouse->pktcnt == 6) { - alps_process_packet(psmouse); + if (!psmouse->badparity) + alps_process_packet(psmouse); return PSMOUSE_FULL_PACKET; } diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b27684f..813dde7 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -324,6 +324,9 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) if (psmouse->pktcnt < psmouse->pktsize) return PSMOUSE_GOOD_DATA; + if (psmouse->pktcnt == psmouse->pktsize && psmouse->badparity) + return PSMOUSE_FULL_PACKET; + if (etd->debug > 1) elantech_packet_dump(psmouse->packet, psmouse->pktsize); diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 9169d15..c06439e 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -187,7 +187,8 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) } if (psmouse->pktcnt >= psmouse->pktsize) { - hgpk_process_packet(psmouse); + if (!psmouse->badparity) + hgpk_process_packet(psmouse); return PSMOUSE_FULL_PACKET; } diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 7c1d7d4..e4d1bac 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -138,6 +138,9 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) unsigned char *packet = psmouse->packet; bool relative_packet = packet[0] & 0x08; + if (psmouse->pktcnt == 1 && psmouse->badparity) + return PSMOUSE_BAD_DATA; + if (relative_packet || !lifebook_use_6byte_proto) { if (psmouse->pktcnt != 3) return PSMOUSE_GOOD_DATA; @@ -166,6 +169,9 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) } } + if (psmouse->badparity) + return PSMOUSE_FULL_PACKET; + if (relative_packet) { if (!dev2) printk(KERN_WARNING "lifebook.c: got relative packet " diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 543c240..7d41ddb 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -51,6 +51,9 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) * Full packet accumulated, process it */ + if (psmouse->badparity) + return PSMOUSE_FULL_PACKET; + if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) { /* Logitech extended packet */ diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index d8c0c8d..8aa033d 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -133,6 +133,9 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) * Full packet accumulated, process it */ + if (psmouse->badparity) + return PSMOUSE_FULL_PACKET; + /* * Scroll wheel on IntelliMice, scroll buttons on NetMice */ @@ -217,6 +220,7 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) { psmouse->state = new_state; + psmouse->badparity = 0; psmouse->pktcnt = psmouse->out_of_sync_cnt = 0; psmouse->ps2dev.flags = 0; psmouse->last = jiffies; @@ -257,10 +261,12 @@ static int psmouse_handle_byte(struct psmouse *psmouse) return -1; } } + psmouse->badparity = 0; psmouse->pktcnt = 0; break; case PSMOUSE_FULL_PACKET: + psmouse->badparity = 0; psmouse->pktcnt = 0; if (psmouse->out_of_sync_cnt) { psmouse->out_of_sync_cnt = 0; @@ -270,6 +276,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse) break; case PSMOUSE_GOOD_DATA: + psmouse->badparity = 0; break; } return 0; @@ -293,8 +300,12 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", flags & SERIO_TIMEOUT ? " timeout" : "", flags & SERIO_PARITY ? " bad parity" : ""); - ps2_cmd_aborted(&psmouse->ps2dev); - goto out; + if (flags & SERIO_TIMEOUT) { + ps2_cmd_aborted(&psmouse->ps2dev); + goto out; + } else { + psmouse->badparity = 1; + } } if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK)) diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index e053bdd..93ba9df 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -43,6 +43,7 @@ struct psmouse { char *vendor; char *name; unsigned char packet[8]; + int badparity; unsigned char badbyte; unsigned char pktcnt; unsigned char pktsize; diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 81a6b81..0778d84 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c @@ -637,6 +637,9 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) * Full packet accumulated, process it */ + if (psmouse->badparity) + return PSMOUSE_FULL_PACKET; + switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { case FSP_PKT_TYPE_ABS: dev_warn(&psmouse->ps2dev.serio->dev, diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index d3f5243..25ec71c 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -534,6 +534,9 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) struct synaptics_data *priv = psmouse->private; if (psmouse->pktcnt >= 6) { /* Full packet received */ + if (psmouse->badparity) + return PSMOUSE_FULL_PACKET; + if (unlikely(priv->pkt_type == SYN_NEWABS)) priv->pkt_type = synaptics_detect_pkt_type(psmouse); diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c index 909431c..12a1e31 100644 --- a/drivers/input/mouse/touchkit_ps2.c +++ b/drivers/input/mouse/touchkit_ps2.c @@ -59,6 +59,9 @@ static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse) if (psmouse->pktcnt != 5) return PSMOUSE_GOOD_DATA; + if (psmouse->badparity) + return PSMOUSE_FULL_PACKET; + input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet)); input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet)); input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet));