···348 return 0;349}350351+/*352+ * alps_poll() - poll the touchpad for current motion packet.353+ * Used in resync.354+ */355+static int alps_poll(struct psmouse *psmouse)356+{357+ struct alps_data *priv = psmouse->private;358+ unsigned char buf[6];359+ int poll_failed;360+361+ if (priv->i->flags & ALPS_PASS)362+ alps_passthrough_mode(psmouse, 1);363+364+ poll_failed = ps2_command(&psmouse->ps2dev, buf,365+ PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;366+367+ if (priv->i->flags & ALPS_PASS)368+ alps_passthrough_mode(psmouse, 0);369+370+ if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)371+ return -1;372+373+ if ((psmouse->badbyte & 0xc8) == 0x08) {374+/*375+ * Poll the track stick ...376+ */377+ if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))378+ return -1;379+ }380+381+ memcpy(psmouse->packet, buf, sizeof(buf));382+ return 0;383+}384+385static int alps_reconnect(struct psmouse *psmouse)386{387 struct alps_data *priv = psmouse->private;···451 input_register_device(priv->dev2);452453 psmouse->protocol_handler = alps_process_byte;454+ psmouse->poll = alps_poll;455 psmouse->disconnect = alps_disconnect;456 psmouse->reconnect = alps_reconnect;457 psmouse->pktsize = 6;458+459+ /* We are having trouble resyncing ALPS touchpads so disable it for now */460+ psmouse->resync_time = 0;461462 return 0;463
+1-1
drivers/input/mouse/logips2pp.c
···117 if (psmouse_sliced_command(psmouse, command))118 return -1;119120- if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL))121 return -1;122123 return 0;
···117 if (psmouse_sliced_command(psmouse, command))118 return -1;119120+ if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300))121 return -1;122123 return 0;
+253-65
drivers/input/mouse/psmouse-base.c
···54module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);55MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");5657-static unsigned int psmouse_resetafter;58module_param_named(resetafter, psmouse_resetafter, uint, 0644);59MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");00006061PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,62 NULL,···74PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,75 (void *) offsetof(struct psmouse, resetafter),76 psmouse_show_int_attr, psmouse_set_int_attr);0007778static struct attribute *psmouse_attributes[] = {79 &psmouse_attr_protocol.dattr.attr,80 &psmouse_attr_rate.dattr.attr,81 &psmouse_attr_resolution.dattr.attr,82 &psmouse_attr_resetafter.dattr.attr,083 NULL84};85···105 * is taken in "slow" paths it is not worth it.106 */107static DECLARE_MUTEX(psmouse_sem);00108109struct psmouse_protocol {110 enum psmouse_type type;···188}189190/*191- * psmouse_interrupt() handles incoming characters, either gathering them into192- * packets or passing them to the command routine as command output.00000000000000000000000000000000000000000000000000000000000000000193 */194195static irqreturn_t psmouse_interrupt(struct serio *serio,196 unsigned char data, unsigned int flags, struct pt_regs *regs)197{198 struct psmouse *psmouse = serio_get_drvdata(serio);199- psmouse_ret_t rc;200201 if (psmouse->state == PSMOUSE_IGNORE)202 goto out;···282 if (ps2_handle_response(&psmouse->ps2dev, data))283 goto out;284285- if (psmouse->state == PSMOUSE_INITIALIZING)286 goto out;287288 if (psmouse->state == PSMOUSE_ACTIVATED &&289 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {290- printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",291 psmouse->name, psmouse->phys, psmouse->pktcnt);292- psmouse->pktcnt = 0;000293 }294295- psmouse->last = jiffies;296 psmouse->packet[psmouse->pktcnt++] = data;297-298- if (psmouse->packet[0] == PSMOUSE_RET_BAT) {00299 if (psmouse->pktcnt == 1)300 goto out;301302- if (psmouse->pktcnt == 2) {303- if (psmouse->packet[1] == PSMOUSE_RET_ID) {304- psmouse->state = PSMOUSE_IGNORE;305- serio_reconnect(serio);306- goto out;307- }308- if (psmouse->type == PSMOUSE_SYNAPTICS) {309- /* neither 0xAA nor 0x00 are valid first bytes310- * for a packet in absolute mode311- */312- psmouse->pktcnt = 0;313- goto out;314- }315 }00000000316 }317318- rc = psmouse->protocol_handler(psmouse, regs);319-320- switch (rc) {321- case PSMOUSE_BAD_DATA:322- printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",323- psmouse->name, psmouse->phys, psmouse->pktcnt);324- psmouse->pktcnt = 0;325-326- if (++psmouse->out_of_sync == psmouse->resetafter) {327- psmouse->state = PSMOUSE_IGNORE;328- printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");329- serio_reconnect(psmouse->ps2dev.serio);330- }331- break;332-333- case PSMOUSE_FULL_PACKET:334- psmouse->pktcnt = 0;335- if (psmouse->out_of_sync) {336- psmouse->out_of_sync = 0;337- printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",338- psmouse->name, psmouse->phys);339- }340- break;341-342- case PSMOUSE_GOOD_DATA:343- break;344 }345-out:0000346 return IRQ_HANDLED;347}348···817}818819/*820- * psmouse_set_state() sets new psmouse state and resets all flags and821- * counters while holding serio lock so fighting with interrupt handler822- * is not a concern.823- */824-825-static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)826-{827- serio_pause_rx(psmouse->ps2dev.serio);828- psmouse->state = new_state;829- psmouse->pktcnt = psmouse->out_of_sync = 0;830- psmouse->ps2dev.flags = 0;831- serio_continue_rx(psmouse->ps2dev.serio);832-}833-834-/*835 * psmouse_activate() enables the mouse so that we get motion reports from it.836 */837···844 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);845}846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000847848/*849 * psmouse_cleanup() resets the mouse into power-on state.···976 down(&psmouse_sem);977978 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);00000979980 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {981 parent = serio_get_drvdata(serio->parent);···10191020 psmouse->set_rate = psmouse_set_rate;1021 psmouse->set_resolution = psmouse_set_resolution;01022 psmouse->protocol_handler = psmouse_process_byte;1023 psmouse->pktsize = 3;1024···1034 }1035 else1036 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);0000000000000000010371038 sprintf(psmouse->devname, "%s %s %s",1039 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);···1092 goto out;10931094 ps2_init(&psmouse->ps2dev, serio);01095 psmouse->dev = input_dev;1096 sprintf(psmouse->phys, "%s/input0", serio->phys);1097···1113 psmouse->rate = psmouse_rate;1114 psmouse->resolution = psmouse_resolution;1115 psmouse->resetafter = psmouse_resetafter;01116 psmouse->smartscroll = psmouse_smartscroll;11171118 psmouse_switch_protocol(psmouse, NULL);···14581459static int __init psmouse_init(void)1460{0000001461 serio_register_driver(&psmouse_drv);01462 return 0;1463}14641465static void __exit psmouse_exit(void)1466{1467 serio_unregister_driver(&psmouse_drv);01468}14691470module_init(psmouse_init);
···54module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);55MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");5657+static unsigned int psmouse_resetafter = 5;58module_param_named(resetafter, psmouse_resetafter, uint, 0644);59MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");60+61+static unsigned int psmouse_resync_time = 5;62+module_param_named(resync_time, psmouse_resync_time, uint, 0644);63+MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never).");6465PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,66 NULL,···70PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,71 (void *) offsetof(struct psmouse, resetafter),72 psmouse_show_int_attr, psmouse_set_int_attr);73+PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO,74+ (void *) offsetof(struct psmouse, resync_time),75+ psmouse_show_int_attr, psmouse_set_int_attr);7677static struct attribute *psmouse_attributes[] = {78 &psmouse_attr_protocol.dattr.attr,79 &psmouse_attr_rate.dattr.attr,80 &psmouse_attr_resolution.dattr.attr,81 &psmouse_attr_resetafter.dattr.attr,82+ &psmouse_attr_resync_time.dattr.attr,83 NULL84};85···97 * is taken in "slow" paths it is not worth it.98 */99static DECLARE_MUTEX(psmouse_sem);100+101+static struct workqueue_struct *kpsmoused_wq;102103struct psmouse_protocol {104 enum psmouse_type type;···178}179180/*181+ * __psmouse_set_state() sets new psmouse state and resets all flags.182+ */183+184+static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)185+{186+ psmouse->state = new_state;187+ psmouse->pktcnt = psmouse->out_of_sync = 0;188+ psmouse->ps2dev.flags = 0;189+ psmouse->last = jiffies;190+}191+192+193+/*194+ * psmouse_set_state() sets new psmouse state and resets all flags and195+ * counters while holding serio lock so fighting with interrupt handler196+ * is not a concern.197+ */198+199+static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)200+{201+ serio_pause_rx(psmouse->ps2dev.serio);202+ __psmouse_set_state(psmouse, new_state);203+ serio_continue_rx(psmouse->ps2dev.serio);204+}205+206+/*207+ * psmouse_handle_byte() processes one byte of the input data stream208+ * by calling corresponding protocol handler.209+ */210+211+static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs)212+{213+ psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs);214+215+ switch (rc) {216+ case PSMOUSE_BAD_DATA:217+ if (psmouse->state == PSMOUSE_ACTIVATED) {218+ printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",219+ psmouse->name, psmouse->phys, psmouse->pktcnt);220+ if (++psmouse->out_of_sync == psmouse->resetafter) {221+ __psmouse_set_state(psmouse, PSMOUSE_IGNORE);222+ printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");223+ serio_reconnect(psmouse->ps2dev.serio);224+ return -1;225+ }226+ }227+ psmouse->pktcnt = 0;228+ break;229+230+ case PSMOUSE_FULL_PACKET:231+ psmouse->pktcnt = 0;232+ if (psmouse->out_of_sync) {233+ psmouse->out_of_sync = 0;234+ printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",235+ psmouse->name, psmouse->phys);236+ }237+ break;238+239+ case PSMOUSE_GOOD_DATA:240+ break;241+ }242+ return 0;243+}244+245+/*246+ * psmouse_interrupt() handles incoming characters, either passing them247+ * for normal processing or gathering them as command response.248 */249250static irqreturn_t psmouse_interrupt(struct serio *serio,251 unsigned char data, unsigned int flags, struct pt_regs *regs)252{253 struct psmouse *psmouse = serio_get_drvdata(serio);0254255 if (psmouse->state == PSMOUSE_IGNORE)256 goto out;···208 if (ps2_handle_response(&psmouse->ps2dev, data))209 goto out;210211+ if (psmouse->state <= PSMOUSE_RESYNCING)212 goto out;213214 if (psmouse->state == PSMOUSE_ACTIVATED &&215 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {216+ printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",217 psmouse->name, psmouse->phys, psmouse->pktcnt);218+ psmouse->badbyte = psmouse->packet[0];219+ __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);220+ queue_work(kpsmoused_wq, &psmouse->resync_work);221+ goto out;222 }2230224 psmouse->packet[psmouse->pktcnt++] = data;225+/*226+ * Check if this is a new device announcement (0xAA 0x00)227+ */228+ if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {229 if (psmouse->pktcnt == 1)230 goto out;231232+ if (psmouse->packet[1] == PSMOUSE_RET_ID) {233+ __psmouse_set_state(psmouse, PSMOUSE_IGNORE);234+ serio_reconnect(serio);235+ goto out;000000000236 }237+/*238+ * Not a new device, try processing first byte normally239+ */240+ psmouse->pktcnt = 1;241+ if (psmouse_handle_byte(psmouse, regs))242+ goto out;243+244+ psmouse->packet[psmouse->pktcnt++] = data;245 }246247+/*248+ * See if we need to force resync because mouse was idle for too long249+ */250+ if (psmouse->state == PSMOUSE_ACTIVATED &&251+ psmouse->pktcnt == 1 && psmouse->resync_time &&252+ time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {253+ psmouse->badbyte = psmouse->packet[0];254+ __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);255+ queue_work(kpsmoused_wq, &psmouse->resync_work);256+ goto out;0000000000000000257 }258+259+ psmouse->last = jiffies;260+ psmouse_handle_byte(psmouse, regs);261+262+ out:263 return IRQ_HANDLED;264}265···752}753754/*000000000000000755 * psmouse_activate() enables the mouse so that we get motion reports from it.756 */757···794 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);795}796797+/*798+ * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it.799+ */800+801+static int psmouse_poll(struct psmouse *psmouse)802+{803+ return ps2_command(&psmouse->ps2dev, psmouse->packet,804+ PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));805+}806+807+808+/*809+ * psmouse_resync() attempts to re-validate current protocol.810+ */811+812+static void psmouse_resync(void *p)813+{814+ struct psmouse *psmouse = p, *parent = NULL;815+ struct serio *serio = psmouse->ps2dev.serio;816+ psmouse_ret_t rc = PSMOUSE_GOOD_DATA;817+ int failed = 0, enabled = 0;818+ int i;819+820+ down(&psmouse_sem);821+822+ if (psmouse->state != PSMOUSE_RESYNCING)823+ goto out;824+825+ if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {826+ parent = serio_get_drvdata(serio->parent);827+ psmouse_deactivate(parent);828+ }829+830+/*831+ * Some mice don't ACK commands sent while they are in the middle of832+ * transmitting motion packet. To avoid delay we use ps2_sendbyte()833+ * instead of ps2_command() which would wait for 200ms for an ACK834+ * that may never come.835+ * As an additional quirk ALPS touchpads may not only forget to ACK836+ * disable command but will stop reporting taps, so if we see that837+ * mouse at least once ACKs disable we will do full reconnect if ACK838+ * is missing.839+ */840+ psmouse->num_resyncs++;841+842+ if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {843+ if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command)844+ failed = 1;845+ } else846+ psmouse->acks_disable_command = 1;847+848+/*849+ * Poll the mouse. If it was reset the packet will be shorter than850+ * psmouse->pktsize and ps2_command will fail. We do not expect and851+ * do not handle scenario when mouse "upgrades" its protocol while852+ * disconnected since it would require additional delay. If we ever853+ * see a mouse that does it we'll adjust the code.854+ */855+ if (!failed) {856+ if (psmouse->poll(psmouse))857+ failed = 1;858+ else {859+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);860+ for (i = 0; i < psmouse->pktsize; i++) {861+ psmouse->pktcnt++;862+ rc = psmouse->protocol_handler(psmouse, NULL);863+ if (rc != PSMOUSE_GOOD_DATA)864+ break;865+ }866+ if (rc != PSMOUSE_FULL_PACKET)867+ failed = 1;868+ psmouse_set_state(psmouse, PSMOUSE_RESYNCING);869+ }870+ }871+/*872+ * Now try to enable mouse. We try to do that even if poll failed and also873+ * repeat our attempts 5 times, otherwise we may be left out with disabled874+ * mouse.875+ */876+ for (i = 0; i < 5; i++) {877+ if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {878+ enabled = 1;879+ break;880+ }881+ msleep(200);882+ }883+884+ if (!enabled) {885+ printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n",886+ psmouse->ps2dev.serio->phys);887+ failed = 1;888+ }889+890+ if (failed) {891+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);892+ printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n");893+ serio_reconnect(serio);894+ } else895+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);896+897+ if (parent)898+ psmouse_activate(parent);899+ out:900+ up(&psmouse_sem);901+}902903/*904 * psmouse_cleanup() resets the mouse into power-on state.···821 down(&psmouse_sem);822823 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);824+825+ /* make sure we don't have a resync in progress */826+ up(&psmouse_sem);827+ flush_workqueue(kpsmoused_wq);828+ down(&psmouse_sem);829830 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {831 parent = serio_get_drvdata(serio->parent);···859860 psmouse->set_rate = psmouse_set_rate;861 psmouse->set_resolution = psmouse_set_resolution;862+ psmouse->poll = psmouse_poll;863 psmouse->protocol_handler = psmouse_process_byte;864 psmouse->pktsize = 3;865···873 }874 else875 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);876+877+ /*878+ * If mouse's packet size is 3 there is no point in polling the879+ * device in hopes to detect protocol reset - we won't get less880+ * than 3 bytes response anyhow.881+ */882+ if (psmouse->pktsize == 3)883+ psmouse->resync_time = 0;884+885+ /*886+ * Some smart KVMs fake response to POLL command returning just887+ * 3 bytes and messing up our resync logic, so if initial poll888+ * fails we won't try polling the device anymore. Hopefully889+ * such KVM will maintain initially selected protocol.890+ */891+ if (psmouse->resync_time && psmouse->poll(psmouse))892+ psmouse->resync_time = 0;893894 sprintf(psmouse->devname, "%s %s %s",895 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);···914 goto out;915916 ps2_init(&psmouse->ps2dev, serio);917+ INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);918 psmouse->dev = input_dev;919 sprintf(psmouse->phys, "%s/input0", serio->phys);920···934 psmouse->rate = psmouse_rate;935 psmouse->resolution = psmouse_resolution;936 psmouse->resetafter = psmouse_resetafter;937+ psmouse->resync_time = parent ? 0 : psmouse_resync_time;938 psmouse->smartscroll = psmouse_smartscroll;939940 psmouse_switch_protocol(psmouse, NULL);···12781279static int __init psmouse_init(void)1280{1281+ kpsmoused_wq = create_singlethread_workqueue("kpsmoused");1282+ if (!kpsmoused_wq) {1283+ printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");1284+ return -ENOMEM;1285+ }1286+1287 serio_register_driver(&psmouse_drv);1288+1289 return 0;1290}12911292static void __exit psmouse_exit(void)1293{1294 serio_unregister_driver(&psmouse_drv);1295+ destroy_workqueue(kpsmoused_wq);1296}12971298module_init(psmouse_init);
···652 psmouse->disconnect = synaptics_disconnect;653 psmouse->reconnect = synaptics_reconnect;654 psmouse->pktsize = 6;655+ /* Synaptics can usually stay in sync without extra help */656+ psmouse->resync_time = 0;657658 if (SYN_CAP_PASS_THROUGH(priv->capabilities))659 synaptics_pt_create(psmouse);