From: Dmitry Torokhov do not modify device's properties when probing for protocol extensions on reconnect as it may interfere with reconnect process --- 25-akpm/drivers/input/mouse/logips2pp.c | 168 +++++++++++++++-------------- 25-akpm/drivers/input/mouse/logips2pp.h | 5 25-akpm/drivers/input/mouse/psmouse-base.c | 78 +++++++------ 3 files changed, 137 insertions(+), 114 deletions(-) diff -puN drivers/input/mouse/logips2pp.c~new-set-of-input-patches-atkbd-reconnect-probe drivers/input/mouse/logips2pp.c --- 25/drivers/input/mouse/logips2pp.c~new-set-of-input-patches-atkbd-reconnect-probe 2004-04-21 00:22:47.058881248 -0700 +++ 25-akpm/drivers/input/mouse/logips2pp.c 2004-04-21 00:22:47.066880032 -0700 @@ -89,7 +89,7 @@ static int ps2pp_cmd(struct psmouse *psm * enabled if we do nothing to it. Of course I put this in because I want it * disabled :P * 1 - enabled (if previously disabled, also default) - * 0/2 - disabled + * 0/2 - disabled */ static void ps2pp_set_smartscroll(struct psmouse *psmouse) @@ -103,14 +103,11 @@ static void ps2pp_set_smartscroll(struct psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - if (psmouse_smartscroll == 1) - param[0] = 1; - else - if (psmouse_smartscroll > 2) - return; - - /* else leave param[0] == 0 to disable */ - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + if (psmouse_smartscroll < 2) { + /* 0 - disabled, 1 - enabled */ + param[0] = psmouse_smartscroll; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + } } /* @@ -128,111 +125,128 @@ void ps2pp_set_800dpi(struct psmouse *ps psmouse_command(psmouse, ¶m, PSMOUSE_CMD_SETRES); } + +static int is_model_in_list(unsigned char model, int *model_list) +{ + int i; + + for (i = 0; model_list[i] != -1; i++) + if (model == model_list[i]) + return 1; + return 0; +} + /* - * Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or - * touchpad. + * Set up input device's properties based on the detected mouse model. */ -static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param) +static void ps2pp_set_properties(struct psmouse *psmouse, unsigned char protocol, + unsigned char model, unsigned char buttons) { - int i; static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 }; static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 }; - static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75, - 76, 80, 81, 83, 88, 96, 97, 112, -1 }; static int logitech_mx[] = { 61, 112, -1 }; psmouse->vendor = "Logitech"; - psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); + psmouse->model = model; - if (param[1] < 3) + if (buttons < 3) clear_bit(BTN_MIDDLE, psmouse->dev.keybit); - if (param[1] < 2) + if (buttons < 2) clear_bit(BTN_RIGHT, psmouse->dev.keybit); - psmouse->type = PSMOUSE_PS2; + if (protocol == PSMOUSE_PS2PP) { - for (i = 0; logitech_ps2pp[i] != -1; i++) - if (logitech_ps2pp[i] == psmouse->model) - psmouse->type = PSMOUSE_PS2PP; - - if (psmouse->type == PSMOUSE_PS2PP) { - - for (i = 0; logitech_4btn[i] != -1; i++) - if (logitech_4btn[i] == psmouse->model) - set_bit(BTN_SIDE, psmouse->dev.keybit); - - for (i = 0; logitech_wheel[i] != -1; i++) - if (logitech_wheel[i] == psmouse->model) { - set_bit(REL_WHEEL, psmouse->dev.relbit); - psmouse->name = "Wheel Mouse"; - } + if (is_model_in_list(model, logitech_4btn)) + set_bit(BTN_SIDE, psmouse->dev.keybit); + + if (is_model_in_list(model, logitech_wheel)) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + psmouse->name = "Wheel Mouse"; + } + + if (is_model_in_list(model, logitech_mx)) { + set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(BTN_EXTRA, psmouse->dev.keybit); + set_bit(BTN_BACK, psmouse->dev.keybit); + set_bit(BTN_FORWARD, psmouse->dev.keybit); + set_bit(BTN_TASK, psmouse->dev.keybit); + psmouse->name = "MX Mouse"; + } + } + + if (protocol == PSMOUSE_PS2TPP) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + set_bit(REL_HWHEEL, psmouse->dev.relbit); + psmouse->name = "TouchPad 3"; + } +} - for (i = 0; logitech_mx[i] != -1; i++) - if (logitech_mx[i] == psmouse->model) { - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(BTN_EXTRA, psmouse->dev.keybit); - set_bit(BTN_BACK, psmouse->dev.keybit); - set_bit(BTN_FORWARD, psmouse->dev.keybit); - set_bit(BTN_TASK, psmouse->dev.keybit); - psmouse->name = "MX Mouse"; - } /* - * Do Logitech PS2++ / PS2T++ magic init. + * Logitech magic init. Detect whether the mouse is a Logitech one + * and its exact model and try turning on extended protocol for ones + * that support it. */ - if (psmouse->model == 97) { /* TouchPad 3 */ +int ps2pp_init(struct psmouse *psmouse, int set_properties) +{ + static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75, + 76, 80, 81, 83, 88, 96, 97, 112, -1 }; + unsigned char param[4]; + unsigned char protocol = PSMOUSE_PS2; + unsigned char model, buttons; - set_bit(REL_WHEEL, psmouse->dev.relbit); - set_bit(REL_HWHEEL, psmouse->dev.relbit); + param[0] = 0; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); + param[1] = 0; + psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); - param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */ + if (param[1] != 0) { + model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); + buttons = param[1]; +/* + * Do Logitech PS2++ / PS2T++ magic init. + */ + if (model == 97) { /* Touch Pad 3 */ + + /* Unprotect RAM */ + param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; psmouse_command(psmouse, param, 0x30d1); - param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */ + /* Enable features */ + param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; psmouse_command(psmouse, param, 0x30d1); - param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */ + /* Enable PS2++ */ + param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; psmouse_command(psmouse, param, 0x30d1); param[0] = 0; if (!psmouse_command(psmouse, param, 0x13d1) && - param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { - psmouse->name = "TouchPad 3"; - return PSMOUSE_PS2TPP; + param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { + protocol = PSMOUSE_PS2TPP; } - } else { + } else if (is_model_in_list(model, logitech_ps2pp)) { param[0] = param[1] = param[2] = 0; ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */ ps2pp_cmd(psmouse, param, 0xDB); - if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 && - (param[2] & 3) == ((param[1] >> 2) & 3)) { - ps2pp_set_smartscroll(psmouse); - return PSMOUSE_PS2PP; + if ((param[0] & 0x78) == 0x48 && + (param[1] & 0xf3) == 0xc2 && + (param[2] & 0x03) == ((param[1] >> 2) & 3)) { + ps2pp_set_smartscroll(psmouse); + protocol = PSMOUSE_PS2PP; } } - } - - return 0; -} -/* - * Logitech magic init. - */ -int ps2pp_detect(struct psmouse *psmouse) -{ - unsigned char param[4]; - - param[0] = 0; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - param[1] = 0; - psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); + if (set_properties) + ps2pp_set_properties(psmouse, protocol, model, buttons); + } - return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0; + return protocol; } diff -puN drivers/input/mouse/logips2pp.h~new-set-of-input-patches-atkbd-reconnect-probe drivers/input/mouse/logips2pp.h --- 25/drivers/input/mouse/logips2pp.h~new-set-of-input-patches-atkbd-reconnect-probe 2004-04-21 00:22:47.059881096 -0700 +++ 25-akpm/drivers/input/mouse/logips2pp.h 2004-04-21 00:22:47.066880032 -0700 @@ -10,8 +10,9 @@ #ifndef _LOGIPS2PP_H #define _LOGIPS2PP_H -struct psmouse; + void ps2pp_process_packet(struct psmouse *psmouse); void ps2pp_set_800dpi(struct psmouse *psmouse); -int ps2pp_detect(struct psmouse *psmouse); +int ps2pp_init(struct psmouse *psmouse, int set_properties); + #endif diff -puN drivers/input/mouse/psmouse-base.c~new-set-of-input-patches-atkbd-reconnect-probe drivers/input/mouse/psmouse-base.c --- 25/drivers/input/mouse/psmouse-base.c~new-set-of-input-patches-atkbd-reconnect-probe 2004-04-21 00:22:47.061880792 -0700 +++ 25-akpm/drivers/input/mouse/psmouse-base.c 2004-04-21 00:22:47.067879880 -0700 @@ -410,22 +410,21 @@ static int im_explorer_detect(struct psm * the mouse may have. */ -static int psmouse_extensions(struct psmouse *psmouse, unsigned int max_proto) +static int psmouse_extensions(struct psmouse *psmouse, + unsigned int max_proto, int set_properties) { int synaptics_hardware = 0; - psmouse->vendor = "Generic"; - psmouse->name = "Mouse"; - psmouse->model = 0; - psmouse->protocol_handler = psmouse_process_byte; - /* * Try Synaptics TouchPad */ if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) { synaptics_hardware = 1; - psmouse->vendor = "Synaptics"; - psmouse->name = "TouchPad"; + + if (set_properties) { + psmouse->vendor = "Synaptics"; + psmouse->name = "TouchPad"; + } if (max_proto > PSMOUSE_IMEX) { if (synaptics_init(psmouse) == 0) @@ -444,33 +443,44 @@ static int psmouse_extensions(struct psm } if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) { - set_bit(BTN_EXTRA, psmouse->dev.keybit); - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(REL_WHEEL, psmouse->dev.relbit); - psmouse->vendor = "Genius"; - psmouse->name = "Wheel Mouse"; + if (set_properties) { + set_bit(BTN_EXTRA, psmouse->dev.keybit); + set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(REL_WHEEL, psmouse->dev.relbit); + psmouse->vendor = "Genius"; + psmouse->name = "Wheel Mouse"; + } + return PSMOUSE_GENPS; } if (max_proto > PSMOUSE_IMEX) { - int type = ps2pp_detect(psmouse); - if (type) + int type = ps2pp_init(psmouse, set_properties); + if (type > PSMOUSE_PS2) return type; } if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) { - set_bit(REL_WHEEL, psmouse->dev.relbit); + + if (set_properties) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + if (!psmouse->name) + psmouse->name = "Wheel Mouse"; + } if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) { - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(BTN_EXTRA, psmouse->dev.keybit); - psmouse->name = "Explorer Mouse"; + if (!set_properties) { + set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(BTN_EXTRA, psmouse->dev.keybit); + if (!psmouse->name) + psmouse->name = "Explorer Mouse"; + } + return PSMOUSE_IMEX; } - psmouse->name = "Wheel Mouse"; return PSMOUSE_IMPS; } @@ -520,12 +530,7 @@ static int psmouse_probe(struct psmouse if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS)) printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys); -/* - * And here we try to determine if it has any extensions over the - * basic PS/2 3-button mouse. - */ - - return psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto); + return 0; } /* @@ -663,7 +668,6 @@ static void psmouse_connect(struct serio psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); - psmouse->state = PSMOUSE_CMD_MODE; psmouse->serio = serio; psmouse->dev.private = psmouse; @@ -675,13 +679,21 @@ static void psmouse_connect(struct serio return; } - if (psmouse_probe(psmouse) <= 0) { + if (psmouse_probe(psmouse) < 0) { serio_close(serio); kfree(psmouse); serio->private = NULL; return; } + psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); + if (!psmouse->vendor) + psmouse->vendor = "Generic"; + if (!psmouse->name) + psmouse->name = "Mouse"; + if (!psmouse->protocol_handler) + psmouse->protocol_handler = psmouse_process_byte; + sprintf(psmouse->devname, "%s %s %s", psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name); sprintf(psmouse->phys, "%s/input0", @@ -715,28 +727,24 @@ static int psmouse_reconnect(struct seri { struct psmouse *psmouse = serio->private; struct serio_dev *dev = serio->dev; - int old_type; if (!dev || !psmouse) { printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n"); return -1; } - old_type = psmouse->type; - psmouse->state = PSMOUSE_CMD_MODE; - psmouse->type = psmouse->acking = 0; - psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0; + psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0; if (psmouse->reconnect) { if (psmouse->reconnect(psmouse)) return -1; - } else if (psmouse_probe(psmouse) != old_type) + } else if (psmouse_probe(psmouse) < 0 || + psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0)) return -1; /* ok, the device type (and capabilities) match the old one, * we can continue using it, complete intialization */ - psmouse->type = old_type; psmouse_initialize(psmouse); if (psmouse->ptport) { _