Input: psmouse - limit protocols that we try on passthrough ports
Subsystems (2)
Dmitry Torokhov
maintainerPATCH 1/1 Input: psmouse - limit protocols that we try on passthrough ports
PS/2 protocol is slow, and using it with pass-through port (where we encapsulate PS/2 into PS/2) is slower yet so it takes quite a bit of time to do full protocol discovery for device attached to a pass-through port. However, so far we have not see anything but tackpoint or basic PS/2 device on pass-through ports, so let's limit protocols that we probe there to Trackpoint, IntelliMouse Explorer, IntelliMouse, and bare PS/2 protocol, and avoid other extended protocols, such as Synaptics, ALPS, etc.
--- drivers/input/mouse/focaltech.c | 4 +- drivers/input/mouse/psmouse-base.c | 575 +++++++++++++++++++------------------ 2 files changed, 297 insertions(+), 282 deletions(-)
drivers/input/mouse/focaltech.c +1 -3
@@ -461,9 +461,7 @@ fail:int focaltech_init (struct psmouse *psmouse) { -focaltech_reset (psmouse); - -return 0 ; +return -ENOSYS ; }#endif /* CONFIG_MOUSE_PS2_FOCALTECH */
drivers/input/mouse/psmouse-base.c +296 -279
635 lines not on this page · raw message
Signature · 5 lines
2.6.0.rc2.230.g3dd15c0 -- Dmitry
Hi Dmitry,
Quoted 4 lines · Dmitry Torokhov
PS/2 protocol is slow, and using it with pass-through port (where we encapsulate PS/2 into PS/2) is slower yet so it takes quite a bit of time to do full protocol discovery for device attached to a pass-through port. However, so far we have not see anything but tackpoint or basic PS/2 device
s/tackpoint/trackpoint/
Quoted 15 lines
on pass-through ports, so let's limit protocols that we probe there to Trackpoint, IntelliMouse Explorer, IntelliMouse, and bare PS/2 protocol, and avoid other extended protocols, such as Synaptics, ALPS, etc.
Signed-off-by Dmitry Torokhov <[email protected]>--- drivers/input/mouse/focaltech.c | 4 +- drivers/input/mouse/psmouse-base.c | 575 +++++++++++++++++++------------------ 2 files changed, 297 insertions(+), 282 deletions(-)drivers/input/mouse/focaltech.c +0
-0
drivers/input/mouse/focaltech.c fail: · line 467
Quoted 10 lines
drivers/input/mouse/focaltech.c +1
-3@@ -461,9 +461,7 @@ fail:int focaltech_init (struct psmouse *psmouse) { -focaltech_reset (psmouse); - -return 0 ; +return -ENOSYS ; }#endif /* CONFIG_MOUSE_PS2_FOCALTECH */
This seems like an unrelated change, and it seem wrong to me.
Quoted 640 lines
drivers/input/mouse/psmouse-base.c +289
-279@@ -119,6 +119,7 @@ struct psmouse_protocol {enum psmouse_type type;bool maxproto;bool ignore_parity;/* Protocol should ignore parity errors from KBC */ +bool try_passthru;/* Try protocol also on passthrough ports */ const char *name;const char *alias;int (*detect)(struct psmouse *,bool );@@ -699,284 +700,6 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties)return 0 ; } -/* -* Apply default settings to the psmouse structure. Most of them will -* be overridden by individual protocol initialization routines. -*/ - -static void psmouse_apply_defaults (struct psmouse *psmouse) -{ -struct input_dev *input_dev = psmouse->dev; - -memset (input_dev->evbit,0 ,sizeof (input_dev->evbit)); -memset (input_dev->keybit,0 ,sizeof (input_dev->keybit)); -memset (input_dev->relbit,0 ,sizeof (input_dev->relbit)); -memset (input_dev->absbit,0 ,sizeof (input_dev->absbit)); -memset (input_dev->mscbit,0 ,sizeof (input_dev->mscbit)); - -__set_bit (EV_KEY , input_dev->evbit); -__set_bit (EV_REL , input_dev->evbit); - -__set_bit (BTN_LEFT , input_dev->keybit); -__set_bit (BTN_RIGHT , input_dev->keybit); - -__set_bit (REL_X , input_dev->relbit); -__set_bit (REL_Y , input_dev->relbit); - -__set_bit (INPUT_PROP_POINTER , input_dev->propbit); - - psmouse->set_rate = psmouse_set_rate; - psmouse->set_resolution = psmouse_set_resolution; - psmouse->set_scale = psmouse_set_scale; - psmouse->poll = psmouse_poll; - psmouse->protocol_handler = psmouse_process_byte; - psmouse->pktsize =3 ; - psmouse->reconnect =NULL ; - psmouse->disconnect =NULL ; - psmouse->cleanup =NULL ; - psmouse->pt_activate =NULL ; - psmouse->pt_deactivate =NULL ; -} - -/* -* Apply default settings to the psmouse structure and call specified -* protocol detection or initialization routine. -*/ -static int psmouse_do_detect (int (*detect)(struct psmouse *psmouse, -bool set_properties), -struct psmouse *psmouse,bool set_properties) -{ -if (set_properties) -psmouse_apply_defaults (psmouse); - -return detect (psmouse, set_properties); -} - -/* -* psmouse_extensions() probes for any extensions to the basic PS/2 protocol -* the mouse may have. -*/ - -static int psmouse_extensions (struct psmouse *psmouse, -unsigned int max_proto,bool set_properties) -{ -bool synaptics_hardware = false; - -/* Always check for focaltech, this is safe as it uses pnp-id matching */ -if (psmouse_do_detect (focaltech_detect, psmouse, set_properties) ==0 ) { -if (max_proto >PSMOUSE_IMEX ) { -if (!set_properties ||focaltech_init (psmouse) ==0 ) { -if (IS_ENABLED (CONFIG_MOUSE_PS2_FOCALTECH )) -return PSMOUSE_FOCALTECH ; -/* -* Note that we need to also restrict -* psmouse_max_proto so that psmouse_initialize() -* does not try to reset rate and resolution, -* because even that upsets the device. -*/ - psmouse_max_proto =PSMOUSE_PS2 ; -return PSMOUSE_PS2 ; - } - } - } - -/* -* We always check for lifebook because it does not disturb mouse -* (it only checks DMI information). -*/ -if (psmouse_do_detect (lifebook_detect, psmouse, set_properties) ==0 ) { -if (max_proto >PSMOUSE_IMEX ) { -if (!set_properties ||lifebook_init (psmouse) ==0 ) -return PSMOUSE_LIFEBOOK ; - } - } - -if (psmouse_do_detect (vmmouse_detect, psmouse, set_properties) ==0 ) { -if (max_proto >PSMOUSE_IMEX ) { -if (!set_properties ||vmmouse_init (psmouse) ==0 ) -return PSMOUSE_VMMOUSE ; - } - } - -/* -* Try Kensington ThinkingMouse (we try first, because synaptics probe -* upsets the thinkingmouse). -*/ - -if (max_proto >PSMOUSE_IMEX && -psmouse_do_detect (thinking_detect, psmouse, set_properties) ==0 ) { -return PSMOUSE_THINKPS ; - } - -/* -* Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol -* support is disabled in config - we need to know if it is synaptics so we -* can reset it properly after probing for intellimouse. -*/ -if (max_proto >PSMOUSE_PS2 && -psmouse_do_detect (synaptics_detect, psmouse, set_properties) ==0 ) { - synaptics_hardware = true; - -if (max_proto >PSMOUSE_IMEX ) { -/* -* Try activating protocol, but check if support is enabled first, since -* we try detecting Synaptics even when protocol is disabled. -*/ -if (IS_ENABLED (CONFIG_MOUSE_PS2_SYNAPTICS ) && - (!set_properties ||synaptics_init (psmouse) ==0 )) { -return PSMOUSE_SYNAPTICS ; - } - -/* -* Some Synaptics touchpads can emulate extended protocols (like IMPS/2). -* Unfortunately Logitech/Genius probes confuse some firmware versions so -* we'll have to skip them. -*/ - max_proto =PSMOUSE_IMEX ; - } -/* -* Make sure that touchpad is in relative mode, gestures (taps) are enabled -*/ -synaptics_reset (psmouse); - } - -/* -* Try Cypress Trackpad. -* Must try it before Finger Sensing Pad because Finger Sensing Pad probe -* upsets some modules of Cypress Trackpads. -*/ -if (max_proto >PSMOUSE_IMEX && -cypress_detect (psmouse, set_properties) ==0 ) { -if (IS_ENABLED (CONFIG_MOUSE_PS2_CYPRESS )) { -if (cypress_init (psmouse) ==0 ) -return PSMOUSE_CYPRESS ; - -/* -* Finger Sensing Pad probe upsets some modules of -* Cypress Trackpad, must avoid Finger Sensing Pad -* probe if Cypress Trackpad device detected. -*/ -return PSMOUSE_PS2 ; - } - - max_proto =PSMOUSE_IMEX ; - } - -/* -* Try ALPS TouchPad -*/ -if (max_proto >PSMOUSE_IMEX ) { -ps2_command (&psmouse->ps2dev,NULL ,PSMOUSE_CMD_RESET_DIS ); -if (psmouse_do_detect (alps_detect, - psmouse, set_properties) ==0 ) { -if (!set_properties ||alps_init (psmouse) ==0 ) -return PSMOUSE_ALPS ; -/* -* Init failed, try basic relative protocols -*/ - max_proto =PSMOUSE_IMEX ; - } - } - -/* -* Try OLPC HGPK touchpad. -*/ -if (max_proto >PSMOUSE_IMEX && -psmouse_do_detect (hgpk_detect, psmouse, set_properties) ==0 ) { -if (!set_properties ||hgpk_init (psmouse) ==0 ) -return PSMOUSE_HGPK ; -/* -* Init failed, try basic relative protocols -*/ - max_proto =PSMOUSE_IMEX ; - } - -/* -* Try Elantech touchpad. -*/ -if (max_proto >PSMOUSE_IMEX && -psmouse_do_detect (elantech_detect, psmouse, set_properties) ==0 ) { -if (!set_properties ||elantech_init (psmouse) ==0 ) -return PSMOUSE_ELANTECH ; -/* -* Init failed, try basic relative protocols -*/ - max_proto =PSMOUSE_IMEX ; - } - -if (max_proto >PSMOUSE_IMEX ) { -if (psmouse_do_detect (genius_detect, - psmouse, set_properties) ==0 ) -return PSMOUSE_GENPS ; - -if (psmouse_do_detect (ps2pp_init, - psmouse, set_properties) ==0 ) -return PSMOUSE_PS2PP ; - -if (psmouse_do_detect (trackpoint_detect, - psmouse, set_properties) ==0 ) -return PSMOUSE_TRACKPOINT ; - -if (psmouse_do_detect (touchkit_ps2_detect, - psmouse, set_properties) ==0 ) -return PSMOUSE_TOUCHKIT_PS2 ; - } - -/* -* Try Finger Sensing Pad. We do it here because its probe upsets -* Trackpoint devices (causing TP_READ_ID command to time out). -*/ -if (max_proto >PSMOUSE_IMEX ) { -if (psmouse_do_detect (fsp_detect, - psmouse, set_properties) ==0 ) { -if (!set_properties ||fsp_init (psmouse) ==0 ) -return PSMOUSE_FSP ; -/* -* Init failed, try basic relative protocols -*/ - max_proto =PSMOUSE_IMEX ; - } - } - -/* -* Reset to defaults in case the device got confused by extended -* protocol probes. Note that we follow up with full reset because -* some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. -*/ -ps2_command (&psmouse->ps2dev,NULL ,PSMOUSE_CMD_RESET_DIS ); -psmouse_reset (psmouse); - -if (max_proto >=PSMOUSE_IMEX && -psmouse_do_detect (im_explorer_detect, - psmouse, set_properties) ==0 ) { -return PSMOUSE_IMEX ; - } - -if (max_proto >=PSMOUSE_IMPS && -psmouse_do_detect (intellimouse_detect, - psmouse, set_properties) ==0 ) { -return PSMOUSE_IMPS ; - } - -/* -* Okay, all failed, we have a standard mouse here. The number of the buttons -* is still a question, though. We assume 3. -*/ -psmouse_do_detect (ps2bare_detect, psmouse, set_properties); - -if (synaptics_hardware) { -/* -* We detected Synaptics hardware but it did not respond to IMPS/2 probes. -* We need to reset the touchpad because if there is a track point on the -* pass through port it could get disabled while probing for protocol -* extensions. -*/ -psmouse_reset (psmouse); - } - -return PSMOUSE_PS2 ; -} -static const struct psmouse_protocol psmouse_protocols[] = { { .type =PSMOUSE_PS2 ,@@ -985,6 +708,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = true, .ignore_parity = true, .detect = ps2bare_detect, + .try_passthru = true, },#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP {@@ -1022,6 +746,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = true, .ignore_parity = true, .detect = intellimouse_detect, + .try_passthru = true, }, { .type = PSMOUSE_IMEX,@@ -1030,6 +755,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = true, .ignore_parity = true, .detect = im_explorer_detect, + .try_passthru = true, },#ifdef CONFIG_MOUSE_PS2_SYNAPTICS {@@ -1061,6 +787,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .type = PSMOUSE_LIFEBOOK, .name = "LBPS/2", .alias = "lifebook", + .detect = lifebook_detect, .init = lifebook_init, },#endif @@ -1070,6 +797,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { .name = "TPPS/2", .alias = "trackpoint", .detect = trackpoint_detect, + .try_passthru = true, },#endif #ifdef CONFIG_MOUSE_PS2_TOUCHKIT @@ -1138,7 +866,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { }, }; -static const struct psmouse_protocol *psmouse_protocol_by_type (enum psmouse_type type) +static const struct psmouse_protocol *__psmouse_protocol_by_type (enum psmouse_type type) {int i;@@ -1146,6 +874,17 @@ static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_typeif (psmouse_protocols[i].type == type)return &psmouse_protocols[i]; +return NULL ; +} + +static const struct psmouse_protocol *psmouse_protocol_by_type (enum psmouse_type type) +{ +const struct psmouse_protocol *proto; + + proto =__psmouse_protocol_by_type (type); +if (proto) +return proto; +WARN_ON (1 );return &psmouse_protocols[0 ]; }@@ -1166,6 +905,284 @@ static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name,return NULL ; } +/* +* Apply default settings to the psmouse structure. Most of them will +* be overridden by individual protocol initialization routines. +*/ + +static void psmouse_apply_defaults (struct psmouse *psmouse) +{ +struct input_dev *input_dev = psmouse->dev; + +memset (input_dev->evbit,0 ,sizeof (input_dev->evbit)); +memset (input_dev->keybit,0 ,sizeof (input_dev->keybit)); +memset (input_dev->relbit,0 ,sizeof (input_dev->relbit)); +memset (input_dev->absbit,0 ,sizeof (input_dev->absbit)); +memset (input_dev->mscbit,0 ,sizeof (input_dev->mscbit)); + +__set_bit (EV_KEY , input_dev->evbit); +__set_bit (EV_REL , input_dev->evbit); + +__set_bit (BTN_LEFT , input_dev->keybit); +__set_bit (BTN_RIGHT , input_dev->keybit); + +__set_bit (REL_X , input_dev->relbit); +__set_bit (REL_Y , input_dev->relbit); + +__set_bit (INPUT_PROP_POINTER , input_dev->propbit); + + psmouse->set_rate = psmouse_set_rate; + psmouse->set_resolution = psmouse_set_resolution; + psmouse->set_scale = psmouse_set_scale; + psmouse->poll = psmouse_poll; + psmouse->protocol_handler = psmouse_process_byte; + psmouse->pktsize =3 ; + psmouse->reconnect =NULL ; + psmouse->disconnect =NULL ; + psmouse->cleanup =NULL ; + psmouse->pt_activate =NULL ; + psmouse->pt_deactivate =NULL ; +} + +static bool psmouse_try_protocol (struct psmouse *psmouse, +enum psmouse_type type, +unsigned int *max_proto, +bool set_properties,bool do_init) +{ +const struct psmouse_protocol *proto; + + proto =__psmouse_protocol_by_type (type); +if (!proto) +return false; + +if (psmouse->ps2dev.serio->id.type ==SERIO_PS_PSTHRU && + !proto->try_passthru) { +return false; + } + +if (set_properties) +psmouse_apply_defaults (psmouse); + +if (proto->detect (psmouse, set_properties) !=0 ) +return false; + +if (set_properties && do_init && proto->init) { +if (proto->init (psmouse) !=0 ) { +/* +* We detected device, but init failed. Adjust +* max_proto so we only try standard protocols. +*/ +if (*max_proto >PSMOUSE_IMEX ) + *max_proto =PSMOUSE_IMEX ; + +return false; + } + } + +return true; +} + +/* +* psmouse_extensions() probes for any extensions to the basic PS/2 protocol +* the mouse may have. +*/ + +static int psmouse_extensions (struct psmouse *psmouse, +unsigned int max_proto,bool set_properties) +{ +bool synaptics_hardware = false; + +/* +* Always check for focaltech, this is safe as it uses pnp-id +* matching +*/ +if (psmouse_try_protocol (psmouse,PSMOUSE_FOCALTECH , + &max_proto, set_properties, false)) { +if (max_proto >PSMOUSE_IMEX ) { +if (IS_ENABLED (CONFIG_MOUSE_PS2_FOCALTECH ) && + (!set_properties ||focaltech_init (psmouse) ==0 )) { +return PSMOUSE_FOCALTECH ; + } + } + +/* +* Restrict psmouse_max_proto so that psmouse_initialize() +* does not try to reset rate and resolution, because even +* that upsets the device. +* This also causes us to basically fall through to basic +* protocol detection, where we fully reset the mouse, +* and set it up as bare PS/2 protocol device. +*/ + psmouse_max_proto =PSMOUSE_PS2 ; + } + +/* +* We always check for lifebook because it does not disturb mouse +* (it only checks DMI information). +*/ +if (psmouse_try_protocol (psmouse,PSMOUSE_LIFEBOOK , &max_proto, + set_properties, max_proto >PSMOUSE_IMEX )) +return PSMOUSE_LIFEBOOK ; + +if (psmouse_try_protocol (psmouse,PSMOUSE_VMMOUSE , &max_proto, + set_properties, max_proto >PSMOUSE_IMEX )) +return PSMOUSE_VMMOUSE ; + +/* +* Try Kensington ThinkingMouse (we try first, because Synaptics +* probe upsets the thinkingmouse). +*/ +if (max_proto >PSMOUSE_IMEX && +psmouse_try_protocol (psmouse,PSMOUSE_THINKPS , &max_proto, + set_properties, true)) { +return PSMOUSE_THINKPS ; + } + +/* +* Try Synaptics TouchPad. Note that probing is done even if +* Synaptics protocol support is disabled in config - we need to +* know if it is Synaptics so we can reset it properly after +* probing for IntelliMouse. +*/ +if (max_proto >PSMOUSE_PS2 && +psmouse_try_protocol (psmouse,PSMOUSE_SYNAPTICS , &max_proto, + set_properties, false)) { + synaptics_hardware = true; + +if (max_proto >PSMOUSE_IMEX ) { +/* +* Try activating protocol, but check if support is +* enabled first, since we try detecting Synaptics +* even when protocol is disabled. +*/ +if (IS_ENABLED (CONFIG_MOUSE_PS2_SYNAPTICS ) && + (!set_properties ||synaptics_init (psmouse) ==0 )) { +return PSMOUSE_SYNAPTICS ; + } + +/* +* Some Synaptics touchpads can emulate extended +* protocols (like IMPS/2). Unfortunately +* Logitech/Genius probes confuse some firmware +* versions so we'll have to skip them. +*/ + max_proto =PSMOUSE_IMEX ; + } + +/* +* Make sure that touchpad is in relative mode, gestures +* (taps) are enabled. +*/ +synaptics_reset (psmouse); + } + +/* +* Try Cypress Trackpad. Must try it before Finger Sensing Pad +* because Finger Sensing Pad probe upsets some modules of Cypress +* Trackpads. +*/ +if (max_proto >PSMOUSE_IMEX && +psmouse_try_protocol (psmouse,PSMOUSE_CYPRESS , &max_proto, + set_properties, true)) { +return PSMOUSE_CYPRESS ; + } + +/* +* Try ALPS TouchPad +*/ +if (max_proto >PSMOUSE_IMEX ) { +ps2_command (&psmouse->ps2dev,NULL ,PSMOUSE_CMD_RESET_DIS ); +if (psmouse_try_protocol (psmouse,PSMOUSE_ALPS , + &max_proto, set_properties, true)) +return PSMOUSE_ALPS ; + } + +/* +* Try OLPC HGPK touchpad. +*/ +if (max_proto >PSMOUSE_IMEX && +psmouse_try_protocol (psmouse,PSMOUSE_HGPK , &max_proto, + set_properties, true)) { +return PSMOUSE_HGPK ; + } + +/* +* Try Elantech touchpad. +*/ +if (max_proto >PSMOUSE_IMEX && +psmouse_try_protocol (psmouse,PSMOUSE_ELANTECH , + &max_proto, set_properties, true)) { +return PSMOUSE_ELANTECH ; + } + +if (max_proto >PSMOUSE_IMEX ) { +if (psmouse_try_protocol (psmouse,PSMOUSE_GENPS , + &max_proto, set_properties, true)) +return PSMOUSE_GENPS ; + +if (psmouse_try_protocol (psmouse,PSMOUSE_PS2PP , + &max_proto, set_properties, true)) +return PSMOUSE_PS2PP ; + +if (psmouse_try_protocol (psmouse,PSMOUSE_TRACKPOINT , + &max_proto, set_properties, true)) +return PSMOUSE_TRACKPOINT ; + +if (psmouse_try_protocol (psmouse,PSMOUSE_TOUCHKIT_PS2 , + &max_proto, set_properties, true)) +return PSMOUSE_TOUCHKIT_PS2 ; + } + +/* +* Try Finger Sensing Pad. We do it here because its probe upsets +* Trackpoint devices (causing TP_READ_ID command to time out). +*/ +if (max_proto >PSMOUSE_IMEX && +psmouse_try_protocol (psmouse,PSMOUSE_FSP , + &max_proto, set_properties, true)) { +return PSMOUSE_FSP ; + } + +/* +* Reset to defaults in case the device got confused by extended +* protocol probes. Note that we follow up with full reset because +* some mice put themselves to sleep when they see +* PSMOUSE_RESET_DIS. +*/ +ps2_command (&psmouse->ps2dev,NULL ,PSMOUSE_CMD_RESET_DIS ); +psmouse_reset (psmouse); + +if (max_proto >=PSMOUSE_IMEX && +psmouse_try_protocol (psmouse,PSMOUSE_IMEX , + &max_proto, set_properties, true)) { +return PSMOUSE_IMEX ; + } + +if (max_proto >=PSMOUSE_IMPS && +psmouse_try_protocol (psmouse,PSMOUSE_IMPS , + &max_proto, set_properties, true)) { +return PSMOUSE_IMPS ; + } + +/* +* Okay, all failed, we have a standard mouse here. The number of +* the buttons is still a question, though. We assume 3. +*/ +psmouse_try_protocol (psmouse,PSMOUSE_PS2 , + &max_proto, set_properties, true); + +if (synaptics_hardware) { +/* +* We detected Synaptics hardware but it did not respond to +* IMPS/2 probes. We need to reset the touchpad because if +* there is a track point on the pass through port it could
drivers/input/mouse/psmouse-base.c static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, · line 1188
Quoted 10 lines
drivers/input/mouse/psmouse-base.c +7
-0+* get disabled while probing for protocol extensions. +*/ +psmouse_reset (psmouse); + } + +return PSMOUSE_PS2 ; +}/* * psmouse_probe() probes for a PS/2 mouse.
90 (95?) % of the change here seems to be just moving code around, can you please split this into 2 commits, one which only moves the function blocks as is as a preparation patch and one doing the actual changes ?
Regards,
Hans