Commit b73aa034 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: rearrange activation/children probe sequence in psmouse so

       reconnect on children ports works even after parent port is
       fully activated:
       - when connecting/reconnecting a port always activate it
       - when connecting/reconnecting a pass-throgh port deactivate
         parent first and activate it after connect is done
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 233b7dfd
...@@ -655,6 +655,21 @@ static void psmouse_activate(struct psmouse *psmouse) ...@@ -655,6 +655,21 @@ static void psmouse_activate(struct psmouse *psmouse)
psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
} }
/*
* psmouse_deactivate() puts the mouse into poll mode so that we don't get motion
* reports from it unless we explicitely request it.
*/
static void psmouse_deactivate(struct psmouse *psmouse)
{
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE))
printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n", psmouse->serio->phys);
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
}
/* /*
* psmouse_cleanup() resets the mouse into power-on state. * psmouse_cleanup() resets the mouse into power-on state.
*/ */
...@@ -705,8 +720,14 @@ static void psmouse_connect(struct serio *serio, struct serio_driver *drv) ...@@ -705,8 +720,14 @@ static void psmouse_connect(struct serio *serio, struct serio_driver *drv)
(serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU) (serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
return; return;
if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) /*
* If this is a pass-through port deactivate parent so the device
* connected to this port can be successfully identified
*/
if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
parent = serio->parent->private; parent = serio->parent->private;
psmouse_deactivate(parent);
}
if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL))) if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))
goto out; goto out;
...@@ -766,20 +787,14 @@ static void psmouse_connect(struct serio *serio, struct serio_driver *drv) ...@@ -766,20 +787,14 @@ static void psmouse_connect(struct serio *serio, struct serio_driver *drv)
if (parent && parent->pt_activate) if (parent && parent->pt_activate)
parent->pt_activate(parent); parent->pt_activate(parent);
/*
* OK, the device is ready, we just need to activate it (turn the
* stream mode on). But if mouse has a pass-through port we don't
* want to do it yet to not disturb child detection.
* The child will activate this port when it's ready.
*/
if (serio->child) { if (serio->child) {
/* /*
* Nothing to be done here, serio core will detect that * Nothing to be done here, serio core will detect that
* the driver set serio->child and will register it for us. * the driver set serio->child and will register it for us.
*/ */
printk(KERN_INFO "serio: %s port at %s\n", serio->child->name, psmouse->phys); printk(KERN_INFO "serio: %s port at %s\n", serio->child->name, psmouse->phys);
} else }
psmouse_activate(psmouse); psmouse_activate(psmouse);
out: out:
...@@ -794,20 +809,26 @@ static int psmouse_reconnect(struct serio *serio) ...@@ -794,20 +809,26 @@ static int psmouse_reconnect(struct serio *serio)
struct psmouse *psmouse = serio->private; struct psmouse *psmouse = serio->private;
struct psmouse *parent = NULL; struct psmouse *parent = NULL;
struct serio_driver *drv = serio->drv; struct serio_driver *drv = serio->drv;
int rc = -1;
if (!drv || !psmouse) { if (!drv || !psmouse) {
printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n"); printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
return -1; return -1;
} }
if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
parent = serio->parent->private;
psmouse_deactivate(parent);
}
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
if (psmouse->reconnect) { if (psmouse->reconnect) {
if (psmouse->reconnect(psmouse)) if (psmouse->reconnect(psmouse))
return -1; goto out;
} else if (psmouse_probe(psmouse) < 0 || } else if (psmouse_probe(psmouse) < 0 ||
psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0)) psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
return -1; goto out;
/* ok, the device type (and capabilities) match the old one, /* ok, the device type (and capabilities) match the old one,
* we can continue using it, complete intialization * we can continue using it, complete intialization
...@@ -816,20 +837,18 @@ static int psmouse_reconnect(struct serio *serio) ...@@ -816,20 +837,18 @@ static int psmouse_reconnect(struct serio *serio)
psmouse_initialize(psmouse); psmouse_initialize(psmouse);
if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU)
parent = serio->parent->private;
if (parent && parent->pt_activate) if (parent && parent->pt_activate)
parent->pt_activate(parent); parent->pt_activate(parent);
if (!serio->child)
psmouse_activate(psmouse); psmouse_activate(psmouse);
rc = 0;
out:
/* If this is a pass-through port the parent waits to be activated */ /* If this is a pass-through port the parent waits to be activated */
if (parent) if (parent)
psmouse_activate(parent); psmouse_activate(parent);
return 0; return rc;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define PSMOUSE_CMD_GETID 0x02f2 #define PSMOUSE_CMD_GETID 0x02f2
#define PSMOUSE_CMD_SETRATE 0x10f3 #define PSMOUSE_CMD_SETRATE 0x10f3
#define PSMOUSE_CMD_ENABLE 0x00f4 #define PSMOUSE_CMD_ENABLE 0x00f4
#define PSMOUSE_CMD_DISABLE 0x00f5
#define PSMOUSE_CMD_RESET_DIS 0x00f6 #define PSMOUSE_CMD_RESET_DIS 0x00f6
#define PSMOUSE_CMD_RESET_BAT 0x02ff #define PSMOUSE_CMD_RESET_BAT 0x02ff
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment