Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | From | Dmitry Torokhov <> | Subject | [PATCH 2.6] 3/3 Serio: support reconnecting keeping same input device | Date | Sat, 23 Aug 2003 01:31:53 -0500 |
| |
The patch below introduces a new serio_dev method "reconnect". It's purpose is to re-initialize attached hardware while keeping the same input device.
Reconnect can be used for example during resume or with somewhat broken hardware like my laptop/docking station which resets the touchpad back in relative mode without telling anyone whenever I dock or un-dock. The regular disconnect/connect solution is not working because clients (like XFree) like to keep the original input device open so after connecting the touchpad it will create a brand new input device. With reconnect the driver has an option to re-initialize hardware but keep the same input device (given that hardware didn't change).
If reconnect fails serio automatically fall back to disconnect/reconnect scheme.
What you think?
Dmitry
P.S. I have a new patch for Synaptics touchpad that makes use of this new functionality that I will sent to the LKML shortly
diff -urN --exclude-from=/usr/src/exclude 2.6.0-test4/drivers/input/serio/serio.c linux-2.6.0-test4/drivers/input/serio/serio.c --- 2.6.0-test4/drivers/input/serio/serio.c 2003-08-22 23:33:02.000000000 -0500 +++ linux-2.6.0-test4/drivers/input/serio/serio.c 2003-08-22 23:41:57.000000000 -0500 @@ -55,6 +55,7 @@ EXPORT_SYMBOL(serio_open); EXPORT_SYMBOL(serio_close); EXPORT_SYMBOL(serio_rescan); +EXPORT_SYMBOL(serio_reconnect); struct serio_event { int type; @@ -81,6 +82,7 @@ } #define SERIO_RESCAN 1 +#define SERIO_RECONNECT 2 static DECLARE_WAIT_QUEUE_HEAD(serio_wait); static DECLARE_COMPLETION(serio_exited); @@ -108,6 +110,12 @@ goto event_done; switch (event->type) { + case SERIO_RECONNECT : + if (event->serio->dev && event->serio->dev->reconnect) + if (event->serio->dev->reconnect(event->serio) == 0) + break; + /* reconnect failed - fall through to rescan */ + case SERIO_RESCAN : if (event->serio->dev && event->serio->dev->disconnect) event->serio->dev->disconnect(event->serio); @@ -142,18 +150,27 @@ complete_and_exit(&serio_exited, 0); } -void serio_rescan(struct serio *serio) +static void serio_queue_event(struct serio *serio, int event_type) { struct serio_event *event; - if (!(event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) - return; + if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { + event->type = event_type; + event->serio = serio; + + list_add_tail(&event->node, &serio_event_list); + wake_up(&serio_wait); + } +} - event->type = SERIO_RESCAN; - event->serio = serio; +void serio_rescan(struct serio *serio) +{ + serio_queue_event(serio, SERIO_RESCAN); +} - list_add_tail(&event->node, &serio_event_list); - wake_up(&serio_wait); +void serio_reconnect(struct serio *serio) +{ + serio_queue_event(serio, SERIO_RECONNECT); } irqreturn_t serio_interrupt(struct serio *serio, diff -urN --exclude-from=/usr/src/exclude 2.6.0-test4/include/linux/serio.h linux-2.6.0-test4/include/linux/serio.h --- 2.6.0-test4/include/linux/serio.h 2003-07-27 12:03:20.000000000 -0500 +++ linux-2.6.0-test4/include/linux/serio.h 2003-08-22 23:36:08.000000000 -0500 @@ -53,6 +53,7 @@ irqreturn_t (*interrupt)(struct serio *, unsigned char, unsigned int, struct pt_regs *); void (*connect)(struct serio *, struct serio_dev *dev); + int (*reconnect)(struct serio *); void (*disconnect)(struct serio *); void (*cleanup)(struct serio *); @@ -62,6 +63,7 @@ int serio_open(struct serio *serio, struct serio_dev *dev); void serio_close(struct serio *serio); void serio_rescan(struct serio *serio); +void serio_reconnect(struct serio *serio); irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs); void serio_register_port(struct serio *serio); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |