···348348 return 0;349349}350350351351+/*352352+ * alps_poll() - poll the touchpad for current motion packet.353353+ * Used in resync.354354+ */355355+static int alps_poll(struct psmouse *psmouse)356356+{357357+ struct alps_data *priv = psmouse->private;358358+ unsigned char buf[6];359359+ int poll_failed;360360+361361+ if (priv->i->flags & ALPS_PASS)362362+ alps_passthrough_mode(psmouse, 1);363363+364364+ poll_failed = ps2_command(&psmouse->ps2dev, buf,365365+ PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;366366+367367+ if (priv->i->flags & ALPS_PASS)368368+ alps_passthrough_mode(psmouse, 0);369369+370370+ if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)371371+ return -1;372372+373373+ if ((psmouse->badbyte & 0xc8) == 0x08) {374374+/*375375+ * Poll the track stick ...376376+ */377377+ if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))378378+ return -1;379379+ }380380+381381+ memcpy(psmouse->packet, buf, sizeof(buf));382382+ return 0;383383+}384384+351385static int alps_reconnect(struct psmouse *psmouse)352386{353387 struct alps_data *priv = psmouse->private;···485451 input_register_device(priv->dev2);486452487453 psmouse->protocol_handler = alps_process_byte;454454+ psmouse->poll = alps_poll;488455 psmouse->disconnect = alps_disconnect;489456 psmouse->reconnect = alps_reconnect;490457 psmouse->pktsize = 6;458458+459459+ /* We are having trouble resyncing ALPS touchpads so disable it for now */460460+ psmouse->resync_time = 0;491461492462 return 0;493463
+1-1
drivers/input/mouse/logips2pp.c
···117117 if (psmouse_sliced_command(psmouse, command))118118 return -1;119119120120- if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL))120120+ if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300))121121 return -1;122122123123 return 0;
+253-65
drivers/input/mouse/psmouse-base.c
···5454module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);5555MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");56565757-static unsigned int psmouse_resetafter;5757+static unsigned int psmouse_resetafter = 5;5858module_param_named(resetafter, psmouse_resetafter, uint, 0644);5959MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");6060+6161+static unsigned int psmouse_resync_time = 5;6262+module_param_named(resync_time, psmouse_resync_time, uint, 0644);6363+MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never).");60646165PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,6266 NULL,···7470PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,7571 (void *) offsetof(struct psmouse, resetafter),7672 psmouse_show_int_attr, psmouse_set_int_attr);7373+PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO,7474+ (void *) offsetof(struct psmouse, resync_time),7575+ psmouse_show_int_attr, psmouse_set_int_attr);77767877static struct attribute *psmouse_attributes[] = {7978 &psmouse_attr_protocol.dattr.attr,8079 &psmouse_attr_rate.dattr.attr,8180 &psmouse_attr_resolution.dattr.attr,8281 &psmouse_attr_resetafter.dattr.attr,8282+ &psmouse_attr_resync_time.dattr.attr,8383 NULL8484};8585···10597 * is taken in "slow" paths it is not worth it.10698 */10799static DECLARE_MUTEX(psmouse_sem);100100+101101+static struct workqueue_struct *kpsmoused_wq;108102109103struct psmouse_protocol {110104 enum psmouse_type type;···188178}189179190180/*191191- * psmouse_interrupt() handles incoming characters, either gathering them into192192- * packets or passing them to the command routine as command output.181181+ * __psmouse_set_state() sets new psmouse state and resets all flags.182182+ */183183+184184+static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)185185+{186186+ psmouse->state = new_state;187187+ psmouse->pktcnt = psmouse->out_of_sync = 0;188188+ psmouse->ps2dev.flags = 0;189189+ psmouse->last = jiffies;190190+}191191+192192+193193+/*194194+ * psmouse_set_state() sets new psmouse state and resets all flags and195195+ * counters while holding serio lock so fighting with interrupt handler196196+ * is not a concern.197197+ */198198+199199+static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)200200+{201201+ serio_pause_rx(psmouse->ps2dev.serio);202202+ __psmouse_set_state(psmouse, new_state);203203+ serio_continue_rx(psmouse->ps2dev.serio);204204+}205205+206206+/*207207+ * psmouse_handle_byte() processes one byte of the input data stream208208+ * by calling corresponding protocol handler.209209+ */210210+211211+static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs)212212+{213213+ psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs);214214+215215+ switch (rc) {216216+ case PSMOUSE_BAD_DATA:217217+ if (psmouse->state == PSMOUSE_ACTIVATED) {218218+ printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",219219+ psmouse->name, psmouse->phys, psmouse->pktcnt);220220+ if (++psmouse->out_of_sync == psmouse->resetafter) {221221+ __psmouse_set_state(psmouse, PSMOUSE_IGNORE);222222+ printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");223223+ serio_reconnect(psmouse->ps2dev.serio);224224+ return -1;225225+ }226226+ }227227+ psmouse->pktcnt = 0;228228+ break;229229+230230+ case PSMOUSE_FULL_PACKET:231231+ psmouse->pktcnt = 0;232232+ if (psmouse->out_of_sync) {233233+ psmouse->out_of_sync = 0;234234+ printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",235235+ psmouse->name, psmouse->phys);236236+ }237237+ break;238238+239239+ case PSMOUSE_GOOD_DATA:240240+ break;241241+ }242242+ return 0;243243+}244244+245245+/*246246+ * psmouse_interrupt() handles incoming characters, either passing them247247+ * for normal processing or gathering them as command response.193248 */194249195250static irqreturn_t psmouse_interrupt(struct serio *serio,196251 unsigned char data, unsigned int flags, struct pt_regs *regs)197252{198253 struct psmouse *psmouse = serio_get_drvdata(serio);199199- psmouse_ret_t rc;200254201255 if (psmouse->state == PSMOUSE_IGNORE)202256 goto out;···282208 if (ps2_handle_response(&psmouse->ps2dev, data))283209 goto out;284210285285- if (psmouse->state == PSMOUSE_INITIALIZING)211211+ if (psmouse->state <= PSMOUSE_RESYNCING)286212 goto out;287213288214 if (psmouse->state == PSMOUSE_ACTIVATED &&289215 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {290290- printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",216216+ printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",291217 psmouse->name, psmouse->phys, psmouse->pktcnt);292292- psmouse->pktcnt = 0;218218+ psmouse->badbyte = psmouse->packet[0];219219+ __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);220220+ queue_work(kpsmoused_wq, &psmouse->resync_work);221221+ goto out;293222 }294223295295- psmouse->last = jiffies;296224 psmouse->packet[psmouse->pktcnt++] = data;297297-298298- if (psmouse->packet[0] == PSMOUSE_RET_BAT) {225225+/*226226+ * Check if this is a new device announcement (0xAA 0x00)227227+ */228228+ if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {299229 if (psmouse->pktcnt == 1)300230 goto out;301231302302- if (psmouse->pktcnt == 2) {303303- if (psmouse->packet[1] == PSMOUSE_RET_ID) {304304- psmouse->state = PSMOUSE_IGNORE;305305- serio_reconnect(serio);306306- goto out;307307- }308308- if (psmouse->type == PSMOUSE_SYNAPTICS) {309309- /* neither 0xAA nor 0x00 are valid first bytes310310- * for a packet in absolute mode311311- */312312- psmouse->pktcnt = 0;313313- goto out;314314- }232232+ if (psmouse->packet[1] == PSMOUSE_RET_ID) {233233+ __psmouse_set_state(psmouse, PSMOUSE_IGNORE);234234+ serio_reconnect(serio);235235+ goto out;315236 }237237+/*238238+ * Not a new device, try processing first byte normally239239+ */240240+ psmouse->pktcnt = 1;241241+ if (psmouse_handle_byte(psmouse, regs))242242+ goto out;243243+244244+ psmouse->packet[psmouse->pktcnt++] = data;316245 }317246318318- rc = psmouse->protocol_handler(psmouse, regs);319319-320320- switch (rc) {321321- case PSMOUSE_BAD_DATA:322322- printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",323323- psmouse->name, psmouse->phys, psmouse->pktcnt);324324- psmouse->pktcnt = 0;325325-326326- if (++psmouse->out_of_sync == psmouse->resetafter) {327327- psmouse->state = PSMOUSE_IGNORE;328328- printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");329329- serio_reconnect(psmouse->ps2dev.serio);330330- }331331- break;332332-333333- case PSMOUSE_FULL_PACKET:334334- psmouse->pktcnt = 0;335335- if (psmouse->out_of_sync) {336336- psmouse->out_of_sync = 0;337337- printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",338338- psmouse->name, psmouse->phys);339339- }340340- break;341341-342342- case PSMOUSE_GOOD_DATA:343343- break;247247+/*248248+ * See if we need to force resync because mouse was idle for too long249249+ */250250+ if (psmouse->state == PSMOUSE_ACTIVATED &&251251+ psmouse->pktcnt == 1 && psmouse->resync_time &&252252+ time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {253253+ psmouse->badbyte = psmouse->packet[0];254254+ __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);255255+ queue_work(kpsmoused_wq, &psmouse->resync_work);256256+ goto out;344257 }345345-out:258258+259259+ psmouse->last = jiffies;260260+ psmouse_handle_byte(psmouse, regs);261261+262262+ out:346263 return IRQ_HANDLED;347264}348265···817752}818753819754/*820820- * psmouse_set_state() sets new psmouse state and resets all flags and821821- * counters while holding serio lock so fighting with interrupt handler822822- * is not a concern.823823- */824824-825825-static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)826826-{827827- serio_pause_rx(psmouse->ps2dev.serio);828828- psmouse->state = new_state;829829- psmouse->pktcnt = psmouse->out_of_sync = 0;830830- psmouse->ps2dev.flags = 0;831831- serio_continue_rx(psmouse->ps2dev.serio);832832-}833833-834834-/*835755 * psmouse_activate() enables the mouse so that we get motion reports from it.836756 */837757···844794 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);845795}846796797797+/*798798+ * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it.799799+ */800800+801801+static int psmouse_poll(struct psmouse *psmouse)802802+{803803+ return ps2_command(&psmouse->ps2dev, psmouse->packet,804804+ PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));805805+}806806+807807+808808+/*809809+ * psmouse_resync() attempts to re-validate current protocol.810810+ */811811+812812+static void psmouse_resync(void *p)813813+{814814+ struct psmouse *psmouse = p, *parent = NULL;815815+ struct serio *serio = psmouse->ps2dev.serio;816816+ psmouse_ret_t rc = PSMOUSE_GOOD_DATA;817817+ int failed = 0, enabled = 0;818818+ int i;819819+820820+ down(&psmouse_sem);821821+822822+ if (psmouse->state != PSMOUSE_RESYNCING)823823+ goto out;824824+825825+ if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {826826+ parent = serio_get_drvdata(serio->parent);827827+ psmouse_deactivate(parent);828828+ }829829+830830+/*831831+ * Some mice don't ACK commands sent while they are in the middle of832832+ * transmitting motion packet. To avoid delay we use ps2_sendbyte()833833+ * instead of ps2_command() which would wait for 200ms for an ACK834834+ * that may never come.835835+ * As an additional quirk ALPS touchpads may not only forget to ACK836836+ * disable command but will stop reporting taps, so if we see that837837+ * mouse at least once ACKs disable we will do full reconnect if ACK838838+ * is missing.839839+ */840840+ psmouse->num_resyncs++;841841+842842+ if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {843843+ if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command)844844+ failed = 1;845845+ } else846846+ psmouse->acks_disable_command = 1;847847+848848+/*849849+ * Poll the mouse. If it was reset the packet will be shorter than850850+ * psmouse->pktsize and ps2_command will fail. We do not expect and851851+ * do not handle scenario when mouse "upgrades" its protocol while852852+ * disconnected since it would require additional delay. If we ever853853+ * see a mouse that does it we'll adjust the code.854854+ */855855+ if (!failed) {856856+ if (psmouse->poll(psmouse))857857+ failed = 1;858858+ else {859859+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);860860+ for (i = 0; i < psmouse->pktsize; i++) {861861+ psmouse->pktcnt++;862862+ rc = psmouse->protocol_handler(psmouse, NULL);863863+ if (rc != PSMOUSE_GOOD_DATA)864864+ break;865865+ }866866+ if (rc != PSMOUSE_FULL_PACKET)867867+ failed = 1;868868+ psmouse_set_state(psmouse, PSMOUSE_RESYNCING);869869+ }870870+ }871871+/*872872+ * Now try to enable mouse. We try to do that even if poll failed and also873873+ * repeat our attempts 5 times, otherwise we may be left out with disabled874874+ * mouse.875875+ */876876+ for (i = 0; i < 5; i++) {877877+ if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {878878+ enabled = 1;879879+ break;880880+ }881881+ msleep(200);882882+ }883883+884884+ if (!enabled) {885885+ printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n",886886+ psmouse->ps2dev.serio->phys);887887+ failed = 1;888888+ }889889+890890+ if (failed) {891891+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);892892+ printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n");893893+ serio_reconnect(serio);894894+ } else895895+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);896896+897897+ if (parent)898898+ psmouse_activate(parent);899899+ out:900900+ up(&psmouse_sem);901901+}847902848903/*849904 * psmouse_cleanup() resets the mouse into power-on state.···976821 down(&psmouse_sem);977822978823 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);824824+825825+ /* make sure we don't have a resync in progress */826826+ up(&psmouse_sem);827827+ flush_workqueue(kpsmoused_wq);828828+ down(&psmouse_sem);979829980830 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {981831 parent = serio_get_drvdata(serio->parent);···10198591020860 psmouse->set_rate = psmouse_set_rate;1021861 psmouse->set_resolution = psmouse_set_resolution;862862+ psmouse->poll = psmouse_poll;1022863 psmouse->protocol_handler = psmouse_process_byte;1023864 psmouse->pktsize = 3;1024865···1034873 }1035874 else1036875 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);876876+877877+ /*878878+ * If mouse's packet size is 3 there is no point in polling the879879+ * device in hopes to detect protocol reset - we won't get less880880+ * than 3 bytes response anyhow.881881+ */882882+ if (psmouse->pktsize == 3)883883+ psmouse->resync_time = 0;884884+885885+ /*886886+ * Some smart KVMs fake response to POLL command returning just887887+ * 3 bytes and messing up our resync logic, so if initial poll888888+ * fails we won't try polling the device anymore. Hopefully889889+ * such KVM will maintain initially selected protocol.890890+ */891891+ if (psmouse->resync_time && psmouse->poll(psmouse))892892+ psmouse->resync_time = 0;10378931038894 sprintf(psmouse->devname, "%s %s %s",1039895 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);···1092914 goto out;10939151094916 ps2_init(&psmouse->ps2dev, serio);917917+ INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);1095918 psmouse->dev = input_dev;1096919 sprintf(psmouse->phys, "%s/input0", serio->phys);1097920···1113934 psmouse->rate = psmouse_rate;1114935 psmouse->resolution = psmouse_resolution;1115936 psmouse->resetafter = psmouse_resetafter;937937+ psmouse->resync_time = parent ? 0 : psmouse_resync_time;1116938 psmouse->smartscroll = psmouse_smartscroll;11179391118940 psmouse_switch_protocol(psmouse, NULL);···1458127814591279static int __init psmouse_init(void)14601280{12811281+ kpsmoused_wq = create_singlethread_workqueue("kpsmoused");12821282+ if (!kpsmoused_wq) {12831283+ printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");12841284+ return -ENOMEM;12851285+ }12861286+14611287 serio_register_driver(&psmouse_drv);12881288+14621289 return 0;14631290}1464129114651292static void __exit psmouse_exit(void)14661293{14671294 serio_unregister_driver(&psmouse_drv);12951295+ destroy_workqueue(kpsmoused_wq);14681296}1469129714701298module_init(psmouse_init);
+8-1
drivers/input/mouse/psmouse.h
···77#define PSMOUSE_CMD_GETINFO 0x03e988#define PSMOUSE_CMD_SETSTREAM 0x00ea99#define PSMOUSE_CMD_SETPOLL 0x00f01010-#define PSMOUSE_CMD_POLL 0x03eb1010+#define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */1111#define PSMOUSE_CMD_GETID 0x02f21212#define PSMOUSE_CMD_SETRATE 0x10f31313#define PSMOUSE_CMD_ENABLE 0x00f4···2323enum psmouse_state {2424 PSMOUSE_IGNORE,2525 PSMOUSE_INITIALIZING,2626+ PSMOUSE_RESYNCING,2627 PSMOUSE_CMD_MODE,2728 PSMOUSE_ACTIVATED,2829};···3938 void *private;4039 struct input_dev *dev;4140 struct ps2dev ps2dev;4141+ struct work_struct resync_work;4242 char *vendor;4343 char *name;4444 unsigned char packet[8];4545+ unsigned char badbyte;4546 unsigned char pktcnt;4647 unsigned char pktsize;4748 unsigned char type;4949+ unsigned char acks_disable_command;4850 unsigned int model;4951 unsigned long last;5052 unsigned long out_of_sync;5353+ unsigned long num_resyncs;5154 enum psmouse_state state;5255 char devname[64];5356 char phys[32];···5954 unsigned int rate;6055 unsigned int resolution;6156 unsigned int resetafter;5757+ unsigned int resync_time;6258 unsigned int smartscroll; /* Logitech only */63596460 psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);···68626963 int (*reconnect)(struct psmouse *psmouse);7064 void (*disconnect)(struct psmouse *psmouse);6565+ int (*poll)(struct psmouse *psmouse);71667267 void (*pt_activate)(struct psmouse *psmouse);7368 void (*pt_deactivate)(struct psmouse *psmouse);
+2
drivers/input/mouse/synaptics.c
···652652 psmouse->disconnect = synaptics_disconnect;653653 psmouse->reconnect = synaptics_reconnect;654654 psmouse->pktsize = 6;655655+ /* Synaptics can usually stay in sync without extra help */656656+ psmouse->resync_time = 0;655657656658 if (SYN_CAP_PASS_THROUGH(priv->capabilities))657659 synaptics_pt_create(psmouse);
···37373838 If unsure, say Y.39394040+config USB_HIDINPUT_POWERBOOK4141+ bool "Enable support for iBook/PowerBook special keys"4242+ default n4343+ depends on USB_HIDINPUT4444+ help4545+ Say Y here if you want support for the special keys (Fn, Numlock) on4646+ Apple iBooks and PowerBooks.4747+4848+ If unsure, say N.4949+4050config HID_FF4151 bool "Force feedback support (EXPERIMENTAL)"4252 depends on USB_HIDINPUT && EXPERIMENTAL