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

Input: psmouse - export protocol as a sysfs per-device attribute to allow easy switching at run-time.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

+266 -50
+243 -48
drivers/input/mouse/psmouse-base.c
··· 32 32 MODULE_DESCRIPTION(DRIVER_DESC); 33 33 MODULE_LICENSE("GPL"); 34 34 35 - static unsigned int psmouse_max_proto = -1U; 35 + static unsigned int psmouse_max_proto = PSMOUSE_AUTO; 36 36 static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); 37 37 static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); 38 - static char *psmouse_proto_abbrev[] = { NULL, "bare", NULL, NULL, NULL, "imps", "exps", NULL, NULL, "lifebook" }; 39 38 #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) 40 39 #define param_set_proto_abbrev psmouse_set_maxproto 41 40 #define param_get_proto_abbrev psmouse_get_maxproto 42 41 module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644); 43 - MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, lifebook, any). Useful for KVM switches."); 42 + MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches."); 44 43 45 44 static unsigned int psmouse_resolution = 200; 46 45 module_param_named(resolution, psmouse_resolution, uint, 0644); ··· 57 58 module_param_named(resetafter, psmouse_resetafter, uint, 0644); 58 59 MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); 59 60 61 + PSMOUSE_DEFINE_ATTR(protocol); 60 62 PSMOUSE_DEFINE_ATTR(rate); 61 63 PSMOUSE_DEFINE_ATTR(resolution); 62 64 PSMOUSE_DEFINE_ATTR(resetafter); ··· 77 77 */ 78 78 static DECLARE_MUTEX(psmouse_sem); 79 79 80 - static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "ThinkPS/2", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2", "LBPS/2" }; 80 + struct psmouse_protocol { 81 + enum psmouse_type type; 82 + char *name; 83 + char *alias; 84 + int maxproto; 85 + int (*detect)(struct psmouse *, int); 86 + int (*init)(struct psmouse *); 87 + }; 81 88 82 89 /* 83 90 * psmouse_process_byte() analyzes the PS/2 data stream and reports ··· 424 417 */ 425 418 static int ps2bare_detect(struct psmouse *psmouse, int set_properties) 426 419 { 427 - if (!psmouse->vendor) psmouse->vendor = "Generic"; 428 - if (!psmouse->name) psmouse->name = "Mouse"; 420 + if (set_properties) { 421 + if (!psmouse->vendor) psmouse->vendor = "Generic"; 422 + if (!psmouse->name) psmouse->name = "Mouse"; 423 + } 429 424 430 425 return 0; 431 426 } 427 + 432 428 433 429 /* 434 430 * psmouse_extensions() probes for any extensions to the basic PS/2 protocol ··· 447 437 * We always check for lifebook because it does not disturb mouse 448 438 * (it only checks DMI information). 449 439 */ 450 - if (lifebook_detect(psmouse, set_properties) == 0 || 451 - max_proto == PSMOUSE_LIFEBOOK) { 452 - 440 + if (lifebook_detect(psmouse, set_properties) == 0) { 453 441 if (max_proto > PSMOUSE_IMEX) { 454 442 if (!set_properties || lifebook_init(psmouse) == 0) 455 443 return PSMOUSE_LIFEBOOK; ··· 536 528 537 529 return PSMOUSE_PS2; 538 530 } 531 + 532 + static struct psmouse_protocol psmouse_protocols[] = { 533 + { 534 + .type = PSMOUSE_PS2, 535 + .name = "PS/2", 536 + .alias = "bare", 537 + .maxproto = 1, 538 + .detect = ps2bare_detect, 539 + }, 540 + { 541 + .type = PSMOUSE_PS2PP, 542 + .name = "PS2++", 543 + .alias = "logitech", 544 + .detect = ps2pp_init, 545 + }, 546 + { 547 + .type = PSMOUSE_THINKPS, 548 + .name = "ThinkPS/2", 549 + .alias = "thinkps", 550 + .detect = thinking_detect, 551 + }, 552 + { 553 + .type = PSMOUSE_GENPS, 554 + .name = "GenPS/2", 555 + .alias = "genius", 556 + .detect = genius_detect, 557 + }, 558 + { 559 + .type = PSMOUSE_IMPS, 560 + .name = "ImPS/2", 561 + .alias = "imps", 562 + .maxproto = 1, 563 + .detect = intellimouse_detect, 564 + }, 565 + { 566 + .type = PSMOUSE_IMEX, 567 + .name = "ImExPS/2", 568 + .alias = "exps", 569 + .maxproto = 1, 570 + .detect = im_explorer_detect, 571 + }, 572 + { 573 + .type = PSMOUSE_SYNAPTICS, 574 + .name = "SynPS/2", 575 + .alias = "synaptics", 576 + .detect = synaptics_detect, 577 + .init = synaptics_init, 578 + }, 579 + { 580 + .type = PSMOUSE_ALPS, 581 + .name = "AlpsPS/2", 582 + .alias = "alps", 583 + .detect = alps_detect, 584 + .init = alps_init, 585 + }, 586 + { 587 + .type = PSMOUSE_LIFEBOOK, 588 + .name = "LBPS/2", 589 + .alias = "lifebook", 590 + .init = lifebook_init, 591 + }, 592 + { 593 + .type = PSMOUSE_AUTO, 594 + .name = "auto", 595 + .alias = "any", 596 + .maxproto = 1, 597 + }, 598 + }; 599 + 600 + static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type) 601 + { 602 + int i; 603 + 604 + for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) 605 + if (psmouse_protocols[i].type == type) 606 + return &psmouse_protocols[i]; 607 + 608 + WARN_ON(1); 609 + return &psmouse_protocols[0]; 610 + } 611 + 612 + static struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len) 613 + { 614 + struct psmouse_protocol *p; 615 + int i; 616 + 617 + for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) { 618 + p = &psmouse_protocols[i]; 619 + 620 + if ((strlen(p->name) == len && !strncmp(p->name, name, len)) || 621 + (strlen(p->alias) == len && !strncmp(p->alias, name, len))) 622 + return &psmouse_protocols[i]; 623 + } 624 + 625 + return NULL; 626 + } 627 + 539 628 540 629 /* 541 630 * psmouse_probe() probes for a PS/2 mouse. ··· 785 680 786 681 psmouse = serio_get_drvdata(serio); 787 682 683 + device_remove_file(&serio->dev, &psmouse_attr_protocol); 788 684 device_remove_file(&serio->dev, &psmouse_attr_rate); 789 685 device_remove_file(&serio->dev, &psmouse_attr_resolution); 790 686 device_remove_file(&serio->dev, &psmouse_attr_resetafter); ··· 818 712 up(&psmouse_sem); 819 713 } 820 714 715 + static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) 716 + { 717 + memset(&psmouse->dev, 0, sizeof(struct input_dev)); 718 + 719 + init_input_dev(&psmouse->dev); 720 + 721 + psmouse->dev.private = psmouse; 722 + psmouse->dev.dev = &psmouse->ps2dev.serio->dev; 723 + 724 + psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); 725 + psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 726 + psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); 727 + 728 + psmouse->set_rate = psmouse_set_rate; 729 + psmouse->set_resolution = psmouse_set_resolution; 730 + psmouse->protocol_handler = psmouse_process_byte; 731 + psmouse->pktsize = 3; 732 + 733 + if (proto && (proto->detect || proto->init)) { 734 + if (proto->detect && proto->detect(psmouse, 1) < 0) 735 + return -1; 736 + 737 + if (proto->init && proto->init(psmouse) < 0) 738 + return -1; 739 + 740 + psmouse->type = proto->type; 741 + } 742 + else 743 + psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); 744 + 745 + sprintf(psmouse->devname, "%s %s %s", 746 + psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); 747 + 748 + psmouse->dev.name = psmouse->devname; 749 + psmouse->dev.phys = psmouse->phys; 750 + psmouse->dev.id.bustype = BUS_I8042; 751 + psmouse->dev.id.vendor = 0x0002; 752 + psmouse->dev.id.product = psmouse->type; 753 + psmouse->dev.id.version = psmouse->model; 754 + 755 + return 0; 756 + } 757 + 821 758 /* 822 759 * psmouse_connect() is a callback from the serio module when 823 760 * an unhandled serio port is found. ··· 888 739 889 740 ps2_init(&psmouse->ps2dev, serio); 890 741 sprintf(psmouse->phys, "%s/input0", serio->phys); 891 - psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); 892 - psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 893 - psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); 894 - psmouse->dev.private = psmouse; 895 - psmouse->dev.dev = &serio->dev; 742 + 896 743 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); 897 744 898 745 serio_set_drvdata(serio, psmouse); ··· 912 767 psmouse->resolution = psmouse_resolution; 913 768 psmouse->resetafter = psmouse_resetafter; 914 769 psmouse->smartscroll = psmouse_smartscroll; 915 - psmouse->set_rate = psmouse_set_rate; 916 - psmouse->set_resolution = psmouse_set_resolution; 917 - psmouse->protocol_handler = psmouse_process_byte; 918 - psmouse->pktsize = 3; 919 770 920 - psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); 921 - 922 - sprintf(psmouse->devname, "%s %s %s", 923 - psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name); 924 - 925 - psmouse->dev.name = psmouse->devname; 926 - psmouse->dev.phys = psmouse->phys; 927 - psmouse->dev.id.bustype = BUS_I8042; 928 - psmouse->dev.id.vendor = 0x0002; 929 - psmouse->dev.id.product = psmouse->type; 930 - psmouse->dev.id.version = psmouse->model; 771 + psmouse_switch_protocol(psmouse, NULL); 931 772 932 773 input_register_device(&psmouse->dev); 933 - 934 774 printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); 935 775 936 776 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); ··· 925 795 if (parent && parent->pt_activate) 926 796 parent->pt_activate(parent); 927 797 798 + device_create_file(&serio->dev, &psmouse_attr_protocol); 928 799 device_create_file(&serio->dev, &psmouse_attr_rate); 929 800 device_create_file(&serio->dev, &psmouse_attr_resolution); 930 801 device_create_file(&serio->dev, &psmouse_attr_resetafter); ··· 1077 946 parent = serio_get_drvdata(serio->parent); 1078 947 psmouse_deactivate(parent); 1079 948 } 949 + 1080 950 psmouse_deactivate(psmouse); 1081 951 1082 952 retval = handler(psmouse, buf, count); 1083 953 1084 - psmouse_activate(psmouse); 954 + if (retval != -ENODEV) 955 + psmouse_activate(psmouse); 956 + 1085 957 if (parent) 1086 958 psmouse_activate(parent); 1087 959 ··· 1093 959 out_unpin: 1094 960 serio_unpin_driver(serio); 1095 961 return retval; 962 + } 963 + 964 + static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, char *buf) 965 + { 966 + return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name); 967 + } 968 + 969 + static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *buf, size_t count) 970 + { 971 + struct serio *serio = psmouse->ps2dev.serio; 972 + struct psmouse *parent = NULL; 973 + struct psmouse_protocol *proto; 974 + int retry = 0; 975 + 976 + if (!(proto = psmouse_protocol_by_name(buf, count))) 977 + return -EINVAL; 978 + 979 + if (psmouse->type == proto->type) 980 + return count; 981 + 982 + while (serio->child) { 983 + if (++retry > 3) { 984 + printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n"); 985 + return -EIO; 986 + } 987 + 988 + up(&psmouse_sem); 989 + serio_unpin_driver(serio); 990 + serio_unregister_child_port(serio); 991 + serio_pin_driver_uninterruptible(serio); 992 + down(&psmouse_sem); 993 + 994 + if (serio->drv != &psmouse_drv) 995 + return -ENODEV; 996 + 997 + if (psmouse->type == proto->type) 998 + return count; /* switched by other thread */ 999 + } 1000 + 1001 + if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { 1002 + parent = serio_get_drvdata(serio->parent); 1003 + if (parent->pt_deactivate) 1004 + parent->pt_deactivate(parent); 1005 + } 1006 + 1007 + if (psmouse->disconnect) 1008 + psmouse->disconnect(psmouse); 1009 + 1010 + psmouse_set_state(psmouse, PSMOUSE_IGNORE); 1011 + input_unregister_device(&psmouse->dev); 1012 + 1013 + psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); 1014 + 1015 + if (psmouse_switch_protocol(psmouse, proto) < 0) { 1016 + psmouse_reset(psmouse); 1017 + /* default to PSMOUSE_PS2 */ 1018 + psmouse_switch_protocol(psmouse, &psmouse_protocols[0]); 1019 + } 1020 + 1021 + psmouse_initialize(psmouse); 1022 + psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 1023 + 1024 + input_register_device(&psmouse->dev); 1025 + printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); 1026 + 1027 + if (parent && parent->pt_activate) 1028 + parent->pt_activate(parent); 1029 + 1030 + return count; 1096 1031 } 1097 1032 1098 1033 static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf) ··· 1220 1017 1221 1018 static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) 1222 1019 { 1223 - int i; 1020 + struct psmouse_protocol *proto; 1224 1021 1225 1022 if (!val) 1226 1023 return -EINVAL; 1227 1024 1228 - if (!strncmp(val, "any", 3)) { 1229 - *((unsigned int *)kp->arg) = -1U; 1230 - return 0; 1231 - } 1025 + proto = psmouse_protocol_by_name(val, strlen(val)); 1232 1026 1233 - for (i = 0; i < ARRAY_SIZE(psmouse_proto_abbrev); i++) { 1234 - if (!psmouse_proto_abbrev[i]) 1235 - continue; 1027 + if (!proto || !proto->maxproto) 1028 + return -EINVAL; 1236 1029 1237 - if (!strncmp(val, psmouse_proto_abbrev[i], strlen(psmouse_proto_abbrev[i]))) { 1238 - *((unsigned int *)kp->arg) = i; 1239 - return 0; 1240 - } 1241 - } 1030 + *((unsigned int *)kp->arg) = proto->type; 1242 1031 1243 - return -EINVAL; \ 1032 + return 0; \ 1244 1033 } 1245 1034 1246 1035 static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) 1247 1036 { 1248 - return sprintf(buffer, "%s\n", 1249 - psmouse_max_proto < ARRAY_SIZE(psmouse_proto_abbrev) ? 1250 - psmouse_proto_abbrev[psmouse_max_proto] : "any"); 1037 + int type = *((unsigned int *)kp->arg); 1038 + 1039 + return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name); 1251 1040 } 1252 1041 1253 1042 static int __init psmouse_init(void)
+1
drivers/input/mouse/psmouse.h
··· 78 78 PSMOUSE_SYNAPTICS, 79 79 PSMOUSE_ALPS, 80 80 PSMOUSE_LIFEBOOK, 81 + PSMOUSE_AUTO /* This one should always be last */ 81 82 }; 82 83 83 84 int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
+16 -2
drivers/input/serio/serio.c
··· 42 42 EXPORT_SYMBOL(serio_interrupt); 43 43 EXPORT_SYMBOL(__serio_register_port); 44 44 EXPORT_SYMBOL(serio_unregister_port); 45 + EXPORT_SYMBOL(serio_unregister_child_port); 45 46 EXPORT_SYMBOL(__serio_unregister_port_delayed); 46 47 EXPORT_SYMBOL(__serio_register_driver); 47 48 EXPORT_SYMBOL(serio_unregister_driver); ··· 180 179 spin_lock_irqsave(&serio_event_lock, flags); 181 180 182 181 /* 183 - * Scan event list for the other events for the same serio port, 182 + * Scan event list for the other events for the same serio port, 184 183 * starting with the most recent one. If event is the same we 185 184 * do not need add new one. If event is of different type we 186 185 * need to add this event and should not look further because 187 186 * we need to preseve sequence of distinct events. 188 - */ 187 + */ 189 188 list_for_each_entry_reverse(event, &serio_event_list, node) { 190 189 if (event->object == object) { 191 190 if (event->type == event_type) ··· 651 650 down(&serio_sem); 652 651 serio_disconnect_port(serio); 653 652 serio_destroy_port(serio); 653 + up(&serio_sem); 654 + } 655 + 656 + /* 657 + * Safely unregisters child port if one is present. 658 + */ 659 + void serio_unregister_child_port(struct serio *serio) 660 + { 661 + down(&serio_sem); 662 + if (serio->child) { 663 + serio_disconnect_port(serio->child); 664 + serio_destroy_port(serio->child); 665 + } 654 666 up(&serio_sem); 655 667 } 656 668
+6
include/linux/serio.h
··· 83 83 } 84 84 85 85 void serio_unregister_port(struct serio *serio); 86 + void serio_unregister_child_port(struct serio *serio); 86 87 void __serio_unregister_port_delayed(struct serio *serio, struct module *owner); 87 88 static inline void serio_unregister_port_delayed(struct serio *serio) 88 89 { ··· 152 151 static inline int serio_pin_driver(struct serio *serio) 153 152 { 154 153 return down_interruptible(&serio->drv_sem); 154 + } 155 + 156 + static inline void serio_pin_driver_uninterruptible(struct serio *serio) 157 + { 158 + down(&serio->drv_sem); 155 159 } 156 160 157 161 static inline void serio_unpin_driver(struct serio *serio)