From: Dmitry Torokhov New parameter psmouse_proto to replace psmouse_noext. Allows to specify highest PS/2 protocol extension that kernel has permission to negotiate (bare|imps|exps). psmouse_noext marked as deprecated and emits a warning when used. parameter parsing converted to the new scheme. Documentation/kernel-parameters.txt | 3 drivers/input/mouse/logips2pp.c | 21 +++ drivers/input/mouse/logips2pp.h | 2 drivers/input/mouse/psmouse-base.c | 213 +++++++++++++++++------------------- drivers/input/mouse/synaptics.c | 4 5 files changed, 128 insertions(+), 115 deletions(-) diff -puN Documentation/kernel-parameters.txt~input-02-add-psmouse_proto Documentation/kernel-parameters.txt --- 25/Documentation/kernel-parameters.txt~input-02-add-psmouse_proto 2003-12-16 22:47:29.000000000 -0800 +++ 25-akpm/Documentation/kernel-parameters.txt 2003-12-16 22:47:29.000000000 -0800 @@ -790,7 +790,8 @@ running once the system is up. before loading. See Documentation/ramdisk.txt. - psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions + psmouse_proto= [HW,MOUSE] Highest PS2 mouse protocol extension to + probe for (bare|imps|exps). psmouse_resetafter= [HW,MOUSE] Try to reset Synaptics Touchpad after so many diff -puN drivers/input/mouse/logips2pp.c~input-02-add-psmouse_proto drivers/input/mouse/logips2pp.c --- 25/drivers/input/mouse/logips2pp.c~input-02-add-psmouse_proto 2003-12-16 22:47:29.000000000 -0800 +++ 25-akpm/drivers/input/mouse/logips2pp.c 2003-12-16 22:47:29.000000000 -0800 @@ -143,7 +143,7 @@ void ps2pp_set_800dpi(struct psmouse *ps * touchpad. */ -int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param) +static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param) { int i; static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 }; @@ -227,3 +227,22 @@ int ps2pp_detect_model(struct psmouse *p 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); + + return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0; +} + diff -puN drivers/input/mouse/logips2pp.h~input-02-add-psmouse_proto drivers/input/mouse/logips2pp.h --- 25/drivers/input/mouse/logips2pp.h~input-02-add-psmouse_proto 2003-12-16 22:47:29.000000000 -0800 +++ 25-akpm/drivers/input/mouse/logips2pp.h 2003-12-16 22:47:29.000000000 -0800 @@ -13,5 +13,5 @@ struct psmouse; void ps2pp_process_packet(struct psmouse *psmouse); void ps2pp_set_800dpi(struct psmouse *psmouse); -int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param); +int ps2pp_detect(struct psmouse *psmouse); #endif diff -puN drivers/input/mouse/psmouse-base.c~input-02-add-psmouse_proto drivers/input/mouse/psmouse-base.c --- 25/drivers/input/mouse/psmouse-base.c~input-02-add-psmouse_proto 2003-12-16 22:47:29.000000000 -0800 +++ 25-akpm/drivers/input/mouse/psmouse-base.c 2003-12-16 22:47:29.000000000 -0800 @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -24,23 +25,32 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("PS/2 mouse driver"); -MODULE_PARM(psmouse_noext, "1i"); -MODULE_PARM_DESC(psmouse_noext, "Disable any protocol extensions. Useful for KVM switches."); -MODULE_PARM(psmouse_resolution, "i"); -MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi."); -MODULE_PARM(psmouse_rate, "i"); -MODULE_PARM_DESC(psmouse_rate, "Report rate, in reports per second."); -MODULE_PARM(psmouse_smartscroll, "i"); -MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); -MODULE_PARM(psmouse_resetafter, "i"); -MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never)."); MODULE_LICENSE("GPL"); static int psmouse_noext; +module_param(psmouse_noext, int, 0); +MODULE_PARM_DESC(psmouse_noext, "[DEPRECATED] Disable any protocol extensions. Useful for KVM switches."); + +static char *psmouse_proto; +static unsigned int psmouse_max_proto = -1UL; +module_param(psmouse_proto, charp, 0); +MODULE_PARM_DESC(psmouse_proto, "Highest protocol extension to probe (bare, imps, exps). Useful for KVM switches."); + int psmouse_resolution = 200; +module_param(psmouse_resolution, uint, 0); +MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi."); + unsigned int psmouse_rate = 100; +module_param(psmouse_rate, uint, 0); +MODULE_PARM_DESC(psmouse_rate, "Report rate, in reports per second."); + int psmouse_smartscroll = 1; +module_param(psmouse_smartscroll, bool, 0); +MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); + unsigned int psmouse_resetafter; +module_param(psmouse_resetafter, uint, 0); +MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never)."); static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"}; @@ -258,49 +268,88 @@ int psmouse_command(struct psmouse *psmo } /* + * Genius NetMouse magic init. + */ +static int genius_detect(struct psmouse *psmouse) +{ + unsigned char param[4]; + + param[0] = 3; + 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); + psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); + + return param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55; +} + +/* + * IntelliMouse magic init. + */ +static int intellimouse_detect(struct psmouse *psmouse) +{ + unsigned char param[2]; + + param[0] = 200; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + param[0] = 100; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + param[0] = 80; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + psmouse_command(psmouse, param, PSMOUSE_CMD_GETID); + + return param[0] == 3; +} + +/* + * Try IntelliMouse/Explorer magic init. + */ +static int im_explorer_detect(struct psmouse *psmouse) +{ + unsigned char param[2]; + + param[0] = 200; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + param[0] = 200; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + param[0] = 80; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + psmouse_command(psmouse, param, PSMOUSE_CMD_GETID); + + return param[0] == 4; +} + +/* * psmouse_extensions() probes for any extensions to the basic PS/2 protocol * the mouse may have. */ static int psmouse_extensions(struct psmouse *psmouse) { - unsigned char param[4]; - - param[0] = 0; psmouse->vendor = "Generic"; psmouse->name = "Mouse"; psmouse->model = 0; - if (psmouse_noext) - return PSMOUSE_PS2; - /* * Try Synaptics TouchPad */ - if (synaptics_detect(psmouse) == 0) { + if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) { psmouse->vendor = "Synaptics"; psmouse->name = "TouchPad"; #if CONFIG_MOUSE_PS2_SYNAPTICS - if (synaptics_init(psmouse) == 0) + if (psmouse_max_proto > PSMOUSE_IMEX && synaptics_init(psmouse) == 0) return PSMOUSE_SYNAPTICS; #endif + /* + * Synaptics hardware (according to Peter Berg Larsen) can get confused + * by protocol probes below so we have to stop here + */ return PSMOUSE_PS2; } -/* - * Try Genius NetMouse magic init. - */ - - param[0] = 3; - 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); - psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); - - if (param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) { - + if (psmouse_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); @@ -310,54 +359,16 @@ static int psmouse_extensions(struct psm return PSMOUSE_GENPS; } -/* - * Try Logitech magic ID. - */ - - 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 (param[1]) { - int type = ps2pp_detect_model(psmouse, param); + if (psmouse_max_proto > PSMOUSE_IMEX) { + int type = ps2pp_detect(psmouse); if (type) return type; } -/* - * Try IntelliMouse magic init. - */ - - param[0] = 200; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - param[0] = 100; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - param[0] = 80; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - psmouse_command(psmouse, param, PSMOUSE_CMD_GETID); - - if (param[0] == 3) { - + if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) { set_bit(REL_WHEEL, psmouse->dev.relbit); -/* - * Try IntelliMouse/Explorer magic init. - */ - - param[0] = 200; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - param[0] = 200; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - param[0] = 80; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - psmouse_command(psmouse, param, PSMOUSE_CMD_GETID); - - if (param[0] == 4) { - + if (psmouse_max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) { set_bit(BTN_SIDE, psmouse->dev.keybit); set_bit(BTN_EXTRA, psmouse->dev.keybit); @@ -463,7 +474,7 @@ static void psmouse_initialize(struct ps * We set the mouse report rate, resolution and scaling. */ - if (!psmouse_noext) { + if (psmouse_max_proto != PSMOUSE_PS2) { psmouse_set_rate(psmouse); psmouse_set_resolution(psmouse); psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); @@ -673,47 +684,29 @@ static struct serio_dev psmouse_dev = { .cleanup = psmouse_cleanup, }; -#ifndef MODULE -static int __init psmouse_noext_setup(char *str) +static inline void psmouse_parse_proto(void) { - psmouse_noext = 1; - return 1; -} - -static int __init psmouse_resolution_setup(char *str) -{ - get_option(&str, &psmouse_resolution); - return 1; -} - -static int __init psmouse_smartscroll_setup(char *str) -{ - get_option(&str, &psmouse_smartscroll); - return 1; -} - -static int __init psmouse_resetafter_setup(char *str) -{ - get_option(&str, &psmouse_resetafter); - return 1; -} - -static int __init psmouse_rate_setup(char *str) -{ - get_option(&str, &psmouse_rate); - return 1; + if (psmouse_noext) { + printk(KERN_WARNING "psmouse: 'psmouse_noext' option is deprecated, please use 'psmouse_proto'\n"); + psmouse_max_proto = PSMOUSE_PS2; + } + + /* even is psmouse_noext is present psmouse_proto overrides it */ + if (psmouse_proto) { + if (!strcmp(psmouse_proto, "bare")) + psmouse_max_proto = PSMOUSE_PS2; + else if (!strcmp(psmouse_proto, "imps")) + psmouse_max_proto = PSMOUSE_IMPS; + else if (!strcmp(psmouse_proto, "exps")) + psmouse_max_proto = PSMOUSE_IMEX; + else + printk(KERN_ERR "psmouse: unknown protocol type '%s'\n", psmouse_proto); + } } -__setup("psmouse_noext", psmouse_noext_setup); -__setup("psmouse_resolution=", psmouse_resolution_setup); -__setup("psmouse_smartscroll=", psmouse_smartscroll_setup); -__setup("psmouse_resetafter=", psmouse_resetafter_setup); -__setup("psmouse_rate=", psmouse_rate_setup); - -#endif - int __init psmouse_init(void) { + psmouse_parse_proto(); serio_register_device(&psmouse_dev); return 0; } diff -puN drivers/input/mouse/synaptics.c~input-02-add-psmouse_proto drivers/input/mouse/synaptics.c --- 25/drivers/input/mouse/synaptics.c~input-02-add-psmouse_proto 2003-12-16 22:47:29.000000000 -0800 +++ 25-akpm/drivers/input/mouse/synaptics.c 2003-12-16 22:47:29.000000000 -0800 @@ -377,7 +377,7 @@ static int synaptics_reconnect(struct ps struct synaptics_data *priv = psmouse->private; struct synaptics_data old_priv = *priv; - if (synaptics_detect(psmouse)) + if (!synaptics_detect(psmouse)) return -1; if (synaptics_query_hardware(psmouse)) { @@ -411,7 +411,7 @@ int synaptics_detect(struct psmouse *psm psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); - return param[1] == 0x47 ? 0 : -1; + return param[1] == 0x47; } int synaptics_init(struct psmouse *psmouse) _