aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/psmouse-base.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor_core@ameritech.net>2006-01-14 00:27:37 -0500
committerDmitry Torokhov <dtor_core@ameritech.net>2006-01-14 00:27:37 -0500
commitf0d5c6f419d3a10443f66d6835855837eae4ac4b (patch)
treeedbaf897d4618095a69865f198d26d2d017813d4 /drivers/input/mouse/psmouse-base.c
parentb65d0d1bacfdbb4a134a7ebd16f280d5d42241cb (diff)
Input: psmouse - attempt to re-synchronize mouse every 5 seconds
This should help driver to deal vith KVMs that reset mice when switching between boxes. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
-rw-r--r--drivers/input/mouse/psmouse-base.c316
1 files changed, 252 insertions, 64 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 4d5ecc04c5b6..7665fd9ce559 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -54,10 +54,14 @@ static unsigned int psmouse_smartscroll = 1;
54module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); 54module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);
55MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); 55MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
56 56
57static unsigned int psmouse_resetafter; 57static unsigned int psmouse_resetafter = 5;
58module_param_named(resetafter, psmouse_resetafter, uint, 0644); 58module_param_named(resetafter, psmouse_resetafter, uint, 0644);
59MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); 59MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
60 60
61static unsigned int psmouse_resync_time = 5;
62module_param_named(resync_time, psmouse_resync_time, uint, 0644);
63MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never).");
64
61PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO, 65PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,
62 NULL, 66 NULL,
63 psmouse_attr_show_protocol, psmouse_attr_set_protocol); 67 psmouse_attr_show_protocol, psmouse_attr_set_protocol);
@@ -70,12 +74,16 @@ PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO,
70PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO, 74PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,
71 (void *) offsetof(struct psmouse, resetafter), 75 (void *) offsetof(struct psmouse, resetafter),
72 psmouse_show_int_attr, psmouse_set_int_attr); 76 psmouse_show_int_attr, psmouse_set_int_attr);
77PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO,
78 (void *) offsetof(struct psmouse, resync_time),
79 psmouse_show_int_attr, psmouse_set_int_attr);
73 80
74static struct attribute *psmouse_attributes[] = { 81static struct attribute *psmouse_attributes[] = {
75 &psmouse_attr_protocol.dattr.attr, 82 &psmouse_attr_protocol.dattr.attr,
76 &psmouse_attr_rate.dattr.attr, 83 &psmouse_attr_rate.dattr.attr,
77 &psmouse_attr_resolution.dattr.attr, 84 &psmouse_attr_resolution.dattr.attr,
78 &psmouse_attr_resetafter.dattr.attr, 85 &psmouse_attr_resetafter.dattr.attr,
86 &psmouse_attr_resync_time.dattr.attr,
79 NULL 87 NULL
80}; 88};
81 89
@@ -98,6 +106,8 @@ __obsolete_setup("psmouse_rate=");
98 */ 106 */
99static DECLARE_MUTEX(psmouse_sem); 107static DECLARE_MUTEX(psmouse_sem);
100 108
109static struct workqueue_struct *kpsmoused_wq;
110
101struct psmouse_protocol { 111struct psmouse_protocol {
102 enum psmouse_type type; 112 enum psmouse_type type;
103 char *name; 113 char *name;
@@ -178,15 +188,79 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg
178} 188}
179 189
180/* 190/*
181 * psmouse_interrupt() handles incoming characters, either gathering them into 191 * __psmouse_set_state() sets new psmouse state and resets all flags.
182 * packets or passing them to the command routine as command output. 192 */
193
194static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
195{
196 psmouse->state = new_state;
197 psmouse->pktcnt = psmouse->out_of_sync = 0;
198 psmouse->ps2dev.flags = 0;
199 psmouse->last = jiffies;
200}
201
202
203/*
204 * psmouse_set_state() sets new psmouse state and resets all flags and
205 * counters while holding serio lock so fighting with interrupt handler
206 * is not a concern.
207 */
208
209static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
210{
211 serio_pause_rx(psmouse->ps2dev.serio);
212 __psmouse_set_state(psmouse, new_state);
213 serio_continue_rx(psmouse->ps2dev.serio);
214}
215
216/*
217 * psmouse_handle_byte() processes one byte of the input data stream
218 * by calling corresponding protocol handler.
219 */
220
221static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs)
222{
223 psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs);
224
225 switch (rc) {
226 case PSMOUSE_BAD_DATA:
227 if (psmouse->state == PSMOUSE_ACTIVATED) {
228 printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
229 psmouse->name, psmouse->phys, psmouse->pktcnt);
230 if (++psmouse->out_of_sync == psmouse->resetafter) {
231 __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
232 printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
233 serio_reconnect(psmouse->ps2dev.serio);
234 return -1;
235 }
236 }
237 psmouse->pktcnt = 0;
238 break;
239
240 case PSMOUSE_FULL_PACKET:
241 psmouse->pktcnt = 0;
242 if (psmouse->out_of_sync) {
243 psmouse->out_of_sync = 0;
244 printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
245 psmouse->name, psmouse->phys);
246 }
247 break;
248
249 case PSMOUSE_GOOD_DATA:
250 break;
251 }
252 return 0;
253}
254
255/*
256 * psmouse_interrupt() handles incoming characters, either passing them
257 * for normal processing or gathering them as command response.
183 */ 258 */
184 259
185static irqreturn_t psmouse_interrupt(struct serio *serio, 260static irqreturn_t psmouse_interrupt(struct serio *serio,
186 unsigned char data, unsigned int flags, struct pt_regs *regs) 261 unsigned char data, unsigned int flags, struct pt_regs *regs)
187{ 262{
188 struct psmouse *psmouse = serio_get_drvdata(serio); 263 struct psmouse *psmouse = serio_get_drvdata(serio);
189 psmouse_ret_t rc;
190 264
191 if (psmouse->state == PSMOUSE_IGNORE) 265 if (psmouse->state == PSMOUSE_IGNORE)
192 goto out; 266 goto out;
@@ -208,67 +282,58 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
208 if (ps2_handle_response(&psmouse->ps2dev, data)) 282 if (ps2_handle_response(&psmouse->ps2dev, data))
209 goto out; 283 goto out;
210 284
211 if (psmouse->state == PSMOUSE_INITIALIZING) 285 if (psmouse->state <= PSMOUSE_RESYNCING)
212 goto out; 286 goto out;
213 287
214 if (psmouse->state == PSMOUSE_ACTIVATED && 288 if (psmouse->state == PSMOUSE_ACTIVATED &&
215 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { 289 psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
216 printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", 290 printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
217 psmouse->name, psmouse->phys, psmouse->pktcnt); 291 psmouse->name, psmouse->phys, psmouse->pktcnt);
218 psmouse->pktcnt = 0; 292 psmouse->badbyte = psmouse->packet[0];
293 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
294 queue_work(kpsmoused_wq, &psmouse->resync_work);
295 goto out;
219 } 296 }
220 297
221 psmouse->last = jiffies;
222 psmouse->packet[psmouse->pktcnt++] = data; 298 psmouse->packet[psmouse->pktcnt++] = data;
223 299/*
224 if (psmouse->packet[0] == PSMOUSE_RET_BAT) { 300 * Check if this is a new device announcement (0xAA 0x00)
301 */
302 if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
225 if (psmouse->pktcnt == 1) 303 if (psmouse->pktcnt == 1)
226 goto out; 304 goto out;
227 305
228 if (psmouse->pktcnt == 2) { 306 if (psmouse->packet[1] == PSMOUSE_RET_ID) {
229 if (psmouse->packet[1] == PSMOUSE_RET_ID) { 307 __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
230 psmouse->state = PSMOUSE_IGNORE; 308 serio_reconnect(serio);
231 serio_reconnect(serio); 309 goto out;
232 goto out;
233 }
234 if (psmouse->type == PSMOUSE_SYNAPTICS) {
235 /* neither 0xAA nor 0x00 are valid first bytes
236 * for a packet in absolute mode
237 */
238 psmouse->pktcnt = 0;
239 goto out;
240 }
241 } 310 }
242 } 311/*
243 312 * Not a new device, try processing first byte normally
244 rc = psmouse->protocol_handler(psmouse, regs); 313 */
314 psmouse->pktcnt = 1;
315 if (psmouse_handle_byte(psmouse, regs))
316 goto out;
245 317
246 switch (rc) { 318 psmouse->packet[psmouse->pktcnt++] = data;
247 case PSMOUSE_BAD_DATA: 319 }
248 printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
249 psmouse->name, psmouse->phys, psmouse->pktcnt);
250 psmouse->pktcnt = 0;
251 320
252 if (++psmouse->out_of_sync == psmouse->resetafter) { 321/*
253 psmouse->state = PSMOUSE_IGNORE; 322 * See if we need to force resync because mouse was idle for too long
254 printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); 323 */
255 serio_reconnect(psmouse->ps2dev.serio); 324 if (psmouse->state == PSMOUSE_ACTIVATED &&
256 } 325 psmouse->pktcnt == 1 && psmouse->resync_time &&
257 break; 326 time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
327 psmouse->badbyte = psmouse->packet[0];
328 __psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
329 queue_work(kpsmoused_wq, &psmouse->resync_work);
330 goto out;
331 }
258 332
259 case PSMOUSE_FULL_PACKET: 333 psmouse->last = jiffies;
260 psmouse->pktcnt = 0; 334 psmouse_handle_byte(psmouse, regs);
261 if (psmouse->out_of_sync) {
262 psmouse->out_of_sync = 0;
263 printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
264 psmouse->name, psmouse->phys);
265 }
266 break;
267 335
268 case PSMOUSE_GOOD_DATA: 336 out:
269 break;
270 }
271out:
272 return IRQ_HANDLED; 337 return IRQ_HANDLED;
273} 338}
274 339
@@ -752,21 +817,6 @@ static void psmouse_initialize(struct psmouse *psmouse)
752} 817}
753 818
754/* 819/*
755 * psmouse_set_state() sets new psmouse state and resets all flags and
756 * counters while holding serio lock so fighting with interrupt handler
757 * is not a concern.
758 */
759
760static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
761{
762 serio_pause_rx(psmouse->ps2dev.serio);
763 psmouse->state = new_state;
764 psmouse->pktcnt = psmouse->out_of_sync = 0;
765 psmouse->ps2dev.flags = 0;
766 serio_continue_rx(psmouse->ps2dev.serio);
767}
768
769/*
770 * psmouse_activate() enables the mouse so that we get motion reports from it. 820 * psmouse_activate() enables the mouse so that we get motion reports from it.
771 */ 821 */
772 822
@@ -794,6 +844,111 @@ static void psmouse_deactivate(struct psmouse *psmouse)
794 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 844 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
795} 845}
796 846
847/*
848 * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it.
849 */
850
851static int psmouse_poll(struct psmouse *psmouse)
852{
853 return ps2_command(&psmouse->ps2dev, psmouse->packet,
854 PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
855}
856
857
858/*
859 * psmouse_resync() attempts to re-validate current protocol.
860 */
861
862static void psmouse_resync(void *p)
863{
864 struct psmouse *psmouse = p, *parent = NULL;
865 struct serio *serio = psmouse->ps2dev.serio;
866 psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
867 int failed = 0, enabled = 0;
868 int i;
869
870 down(&psmouse_sem);
871
872 if (psmouse->state != PSMOUSE_RESYNCING)
873 goto out;
874
875 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
876 parent = serio_get_drvdata(serio->parent);
877 psmouse_deactivate(parent);
878 }
879
880/*
881 * Some mice don't ACK commands sent while they are in the middle of
882 * transmitting motion packet. To avoid delay we use ps2_sendbyte()
883 * instead of ps2_command() which would wait for 200ms for an ACK
884 * that may never come.
885 * As an additional quirk ALPS touchpads may not only forget to ACK
886 * disable command but will stop reporting taps, so if we see that
887 * mouse at least once ACKs disable we will do full reconnect if ACK
888 * is missing.
889 */
890 psmouse->num_resyncs++;
891
892 if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {
893 if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command)
894 failed = 1;
895 } else
896 psmouse->acks_disable_command = 1;
897
898/*
899 * Poll the mouse. If it was reset the packet will be shorter than
900 * psmouse->pktsize and ps2_command will fail. We do not expect and
901 * do not handle scenario when mouse "upgrades" its protocol while
902 * disconnected since it would require additional delay. If we ever
903 * see a mouse that does it we'll adjust the code.
904 */
905 if (!failed) {
906 if (psmouse->poll(psmouse))
907 failed = 1;
908 else {
909 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
910 for (i = 0; i < psmouse->pktsize; i++) {
911 psmouse->pktcnt++;
912 rc = psmouse->protocol_handler(psmouse, NULL);
913 if (rc != PSMOUSE_GOOD_DATA)
914 break;
915 }
916 if (rc != PSMOUSE_FULL_PACKET)
917 failed = 1;
918 psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
919 }
920 }
921/*
922 * Now try to enable mouse. We try to do that even if poll failed and also
923 * repeat our attempts 5 times, otherwise we may be left out with disabled
924 * mouse.
925 */
926 for (i = 0; i < 5; i++) {
927 if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
928 enabled = 1;
929 break;
930 }
931 msleep(200);
932 }
933
934 if (!enabled) {
935 printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n",
936 psmouse->ps2dev.serio->phys);
937 failed = 1;
938 }
939
940 if (failed) {
941 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
942 printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n");
943 serio_reconnect(serio);
944 } else
945 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
946
947 if (parent)
948 psmouse_activate(parent);
949 out:
950 up(&psmouse_sem);
951}
797 952
798/* 953/*
799 * psmouse_cleanup() resets the mouse into power-on state. 954 * psmouse_cleanup() resets the mouse into power-on state.
@@ -822,6 +977,11 @@ static void psmouse_disconnect(struct serio *serio)
822 977
823 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 978 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
824 979
980 /* make sure we don't have a resync in progress */
981 up(&psmouse_sem);
982 flush_workqueue(kpsmoused_wq);
983 down(&psmouse_sem);
984
825 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { 985 if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
826 parent = serio_get_drvdata(serio->parent); 986 parent = serio_get_drvdata(serio->parent);
827 psmouse_deactivate(parent); 987 psmouse_deactivate(parent);
@@ -859,6 +1019,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
859 1019
860 psmouse->set_rate = psmouse_set_rate; 1020 psmouse->set_rate = psmouse_set_rate;
861 psmouse->set_resolution = psmouse_set_resolution; 1021 psmouse->set_resolution = psmouse_set_resolution;
1022 psmouse->poll = psmouse_poll;
862 psmouse->protocol_handler = psmouse_process_byte; 1023 psmouse->protocol_handler = psmouse_process_byte;
863 psmouse->pktsize = 3; 1024 psmouse->pktsize = 3;
864 1025
@@ -874,6 +1035,23 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
874 else 1035 else
875 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); 1036 psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
876 1037
1038 /*
1039 * If mouse's packet size is 3 there is no point in polling the
1040 * device in hopes to detect protocol reset - we won't get less
1041 * than 3 bytes response anyhow.
1042 */
1043 if (psmouse->pktsize == 3)
1044 psmouse->resync_time = 0;
1045
1046 /*
1047 * Some smart KVMs fake response to POLL command returning just
1048 * 3 bytes and messing up our resync logic, so if initial poll
1049 * fails we won't try polling the device anymore. Hopefully
1050 * such KVM will maintain initially selected protocol.
1051 */
1052 if (psmouse->resync_time && psmouse->poll(psmouse))
1053 psmouse->resync_time = 0;
1054
877 sprintf(psmouse->devname, "%s %s %s", 1055 sprintf(psmouse->devname, "%s %s %s",
878 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); 1056 psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
879 1057
@@ -914,6 +1092,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
914 goto out; 1092 goto out;
915 1093
916 ps2_init(&psmouse->ps2dev, serio); 1094 ps2_init(&psmouse->ps2dev, serio);
1095 INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);
917 psmouse->dev = input_dev; 1096 psmouse->dev = input_dev;
918 sprintf(psmouse->phys, "%s/input0", serio->phys); 1097 sprintf(psmouse->phys, "%s/input0", serio->phys);
919 1098
@@ -934,6 +1113,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
934 psmouse->rate = psmouse_rate; 1113 psmouse->rate = psmouse_rate;
935 psmouse->resolution = psmouse_resolution; 1114 psmouse->resolution = psmouse_resolution;
936 psmouse->resetafter = psmouse_resetafter; 1115 psmouse->resetafter = psmouse_resetafter;
1116 psmouse->resync_time = parent ? 0 : psmouse_resync_time;
937 psmouse->smartscroll = psmouse_smartscroll; 1117 psmouse->smartscroll = psmouse_smartscroll;
938 1118
939 psmouse_switch_protocol(psmouse, NULL); 1119 psmouse_switch_protocol(psmouse, NULL);
@@ -1278,13 +1458,21 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp)
1278 1458
1279static int __init psmouse_init(void) 1459static int __init psmouse_init(void)
1280{ 1460{
1461 kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
1462 if (!kpsmoused_wq) {
1463 printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");
1464 return -ENOMEM;
1465 }
1466
1281 serio_register_driver(&psmouse_drv); 1467 serio_register_driver(&psmouse_drv);
1468
1282 return 0; 1469 return 0;
1283} 1470}
1284 1471
1285static void __exit psmouse_exit(void) 1472static void __exit psmouse_exit(void)
1286{ 1473{
1287 serio_unregister_driver(&psmouse_drv); 1474 serio_unregister_driver(&psmouse_drv);
1475 destroy_workqueue(kpsmoused_wq);
1288} 1476}
1289 1477
1290module_init(psmouse_init); 1478module_init(psmouse_init);