Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: psmouse - rework setting of BTN_MIDDLE capability

Do not start protocol detection assuming that middle mouse is present,
instead let individual protocols explicitly set this capability.
This fixes issue with Synaptics touchpads pretending that they have
middle button when hardware clearly reports otherwise.

Reported-and-tested-by: Andrey Borzenkov <arvidjaar@mail.ru>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

+38 -31
-13
drivers/input/mouse/hgpk.c
··· 430 430 struct input_dev *dev = psmouse->dev; 431 431 int err; 432 432 433 - /* unset the things that psmouse-base sets which we don't have */ 434 - __clear_bit(BTN_MIDDLE, dev->keybit); 435 - 436 - /* set the things we do have */ 437 - __set_bit(EV_KEY, dev->evbit); 438 - __set_bit(EV_REL, dev->evbit); 439 - 440 - __set_bit(REL_X, dev->relbit); 441 - __set_bit(REL_Y, dev->relbit); 442 - 443 - __set_bit(BTN_LEFT, dev->keybit); 444 - __set_bit(BTN_RIGHT, dev->keybit); 445 - 446 433 /* register handlers */ 447 434 psmouse->protocol_handler = hgpk_process_byte; 448 435 psmouse->poll = hgpk_poll;
+2 -2
drivers/input/mouse/logips2pp.c
··· 404 404 } 405 405 } 406 406 407 - if (buttons < 3) 408 - __clear_bit(BTN_MIDDLE, psmouse->dev->keybit); 407 + if (buttons >= 3) 408 + __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 409 409 410 410 if (model_info) 411 411 ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
+27 -11
drivers/input/mouse/psmouse-base.c
··· 425 425 return -1; 426 426 427 427 if (set_properties) { 428 + __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 428 429 __set_bit(BTN_EXTRA, psmouse->dev->keybit); 429 430 __set_bit(BTN_SIDE, psmouse->dev->keybit); 430 431 __set_bit(REL_WHEEL, psmouse->dev->relbit); ··· 461 460 __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 462 461 __set_bit(REL_WHEEL, psmouse->dev->relbit); 463 462 464 - if (!psmouse->vendor) psmouse->vendor = "Generic"; 465 - if (!psmouse->name) psmouse->name = "Wheel Mouse"; 463 + if (!psmouse->vendor) 464 + psmouse->vendor = "Generic"; 465 + if (!psmouse->name) 466 + psmouse->name = "Wheel Mouse"; 466 467 psmouse->pktsize = 4; 467 468 } 468 469 ··· 507 504 __set_bit(BTN_SIDE, psmouse->dev->keybit); 508 505 __set_bit(BTN_EXTRA, psmouse->dev->keybit); 509 506 510 - if (!psmouse->vendor) psmouse->vendor = "Generic"; 511 - if (!psmouse->name) psmouse->name = "Explorer Mouse"; 507 + if (!psmouse->vendor) 508 + psmouse->vendor = "Generic"; 509 + if (!psmouse->name) 510 + psmouse->name = "Explorer Mouse"; 512 511 psmouse->pktsize = 4; 513 512 } 514 513 ··· 541 536 return -1; 542 537 543 538 if (set_properties) { 539 + __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 544 540 __set_bit(BTN_EXTRA, psmouse->dev->keybit); 545 541 546 542 psmouse->vendor = "Kensington"; ··· 557 551 static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) 558 552 { 559 553 if (set_properties) { 560 - if (!psmouse->vendor) psmouse->vendor = "Generic"; 561 - if (!psmouse->name) psmouse->name = "Mouse"; 554 + if (!psmouse->vendor) 555 + psmouse->vendor = "Generic"; 556 + if (!psmouse->name) 557 + psmouse->name = "Mouse"; 558 + 559 + /* 560 + * We have no way of figuring true number of buttons so let's 561 + * assume that the device has 3. 562 + */ 563 + __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 562 564 } 563 565 564 566 return 0; ··· 581 567 if (set_properties) { 582 568 psmouse->vendor = "Cortron"; 583 569 psmouse->name = "PS/2 Trackball"; 570 + 571 + __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 584 572 __set_bit(BTN_SIDE, psmouse->dev->keybit); 585 573 } 586 574 ··· 1200 1184 mutex_unlock(&psmouse_mutex); 1201 1185 } 1202 1186 1203 - static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse_protocol *proto) 1187 + static int psmouse_switch_protocol(struct psmouse *psmouse, 1188 + const struct psmouse_protocol *proto) 1204 1189 { 1205 1190 struct input_dev *input_dev = psmouse->dev; 1206 1191 1207 1192 input_dev->dev.parent = &psmouse->ps2dev.serio->dev; 1208 1193 1209 1194 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 1210 - input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | 1211 - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); 1195 + input_dev->keybit[BIT_WORD(BTN_MOUSE)] = 1196 + BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); 1212 1197 input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 1213 1198 1214 1199 psmouse->set_rate = psmouse_set_rate; ··· 1226 1209 return -1; 1227 1210 1228 1211 psmouse->type = proto->type; 1229 - } 1230 - else 1212 + } else 1231 1213 psmouse->type = psmouse_extensions(psmouse, 1232 1214 psmouse_max_proto, true); 1233 1215
+1
drivers/input/mouse/sentelic.c
··· 836 836 priv->flags |= FSPDRV_FLAG_EN_OPC; 837 837 838 838 /* Set up various supported input event bits */ 839 + __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 839 840 __set_bit(BTN_BACK, psmouse->dev->keybit); 840 841 __set_bit(BTN_FORWARD, psmouse->dev->keybit); 841 842 __set_bit(REL_WHEEL, psmouse->dev->relbit);
+8 -5
drivers/input/mouse/trackpoint.c
··· 284 284 285 285 int trackpoint_detect(struct psmouse *psmouse, bool set_properties) 286 286 { 287 - struct trackpoint_data *priv; 288 287 struct ps2dev *ps2dev = &psmouse->ps2dev; 289 288 unsigned char firmware_id; 290 289 unsigned char button_info; ··· 300 301 button_info = 0; 301 302 } 302 303 303 - psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); 304 - if (!priv) 304 + psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); 305 + if (!psmouse->private) 305 306 return -1; 306 307 307 308 psmouse->vendor = "IBM"; ··· 310 311 psmouse->reconnect = trackpoint_reconnect; 311 312 psmouse->disconnect = trackpoint_disconnect; 312 313 313 - trackpoint_defaults(priv); 314 + if ((button_info & 0x0f) >= 3) 315 + __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 316 + 317 + trackpoint_defaults(psmouse->private); 314 318 trackpoint_sync(psmouse); 315 319 316 320 error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); ··· 321 319 printk(KERN_ERR 322 320 "trackpoint.c: failed to create sysfs attributes, error: %d\n", 323 321 error); 324 - kfree(priv); 322 + kfree(psmouse->private); 323 + psmouse->private = NULL; 325 324 return -1; 326 325 } 327 326