diff options
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
| -rw-r--r-- | drivers/input/mouse/psmouse-base.c | 99 |
1 files changed, 53 insertions, 46 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index af24313ff5bb..6ee9999a2eaa 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -114,7 +114,7 @@ struct psmouse_protocol { | |||
| 114 | 114 | ||
| 115 | static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs) | 115 | static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs) |
| 116 | { | 116 | { |
| 117 | struct input_dev *dev = &psmouse->dev; | 117 | struct input_dev *dev = psmouse->dev; |
| 118 | unsigned char *packet = psmouse->packet; | 118 | unsigned char *packet = psmouse->packet; |
| 119 | 119 | ||
| 120 | if (psmouse->pktcnt < psmouse->pktsize) | 120 | if (psmouse->pktcnt < psmouse->pktsize) |
| @@ -333,12 +333,11 @@ static int genius_detect(struct psmouse *psmouse, int set_properties) | |||
| 333 | return -1; | 333 | return -1; |
| 334 | 334 | ||
| 335 | if (set_properties) { | 335 | if (set_properties) { |
| 336 | set_bit(BTN_EXTRA, psmouse->dev.keybit); | 336 | set_bit(BTN_EXTRA, psmouse->dev->keybit); |
| 337 | set_bit(BTN_SIDE, psmouse->dev.keybit); | 337 | set_bit(BTN_SIDE, psmouse->dev->keybit); |
| 338 | set_bit(REL_WHEEL, psmouse->dev.relbit); | 338 | set_bit(REL_WHEEL, psmouse->dev->relbit); |
| 339 | 339 | ||
| 340 | psmouse->vendor = "Genius"; | 340 | psmouse->vendor = "Genius"; |
| 341 | psmouse->name = "Wheel Mouse"; | ||
| 342 | psmouse->pktsize = 4; | 341 | psmouse->pktsize = 4; |
| 343 | } | 342 | } |
| 344 | 343 | ||
| @@ -365,8 +364,8 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties) | |||
| 365 | return -1; | 364 | return -1; |
| 366 | 365 | ||
| 367 | if (set_properties) { | 366 | if (set_properties) { |
| 368 | set_bit(BTN_MIDDLE, psmouse->dev.keybit); | 367 | set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
| 369 | set_bit(REL_WHEEL, psmouse->dev.relbit); | 368 | set_bit(REL_WHEEL, psmouse->dev->relbit); |
| 370 | 369 | ||
| 371 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 370 | if (!psmouse->vendor) psmouse->vendor = "Generic"; |
| 372 | if (!psmouse->name) psmouse->name = "Wheel Mouse"; | 371 | if (!psmouse->name) psmouse->name = "Wheel Mouse"; |
| @@ -398,10 +397,10 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) | |||
| 398 | return -1; | 397 | return -1; |
| 399 | 398 | ||
| 400 | if (set_properties) { | 399 | if (set_properties) { |
| 401 | set_bit(BTN_MIDDLE, psmouse->dev.keybit); | 400 | set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
| 402 | set_bit(REL_WHEEL, psmouse->dev.relbit); | 401 | set_bit(REL_WHEEL, psmouse->dev->relbit); |
| 403 | set_bit(BTN_SIDE, psmouse->dev.keybit); | 402 | set_bit(BTN_SIDE, psmouse->dev->keybit); |
| 404 | set_bit(BTN_EXTRA, psmouse->dev.keybit); | 403 | set_bit(BTN_EXTRA, psmouse->dev->keybit); |
| 405 | 404 | ||
| 406 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 405 | if (!psmouse->vendor) psmouse->vendor = "Generic"; |
| 407 | if (!psmouse->name) psmouse->name = "Explorer Mouse"; | 406 | if (!psmouse->name) psmouse->name = "Explorer Mouse"; |
| @@ -433,7 +432,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties) | |||
| 433 | return -1; | 432 | return -1; |
| 434 | 433 | ||
| 435 | if (set_properties) { | 434 | if (set_properties) { |
| 436 | set_bit(BTN_EXTRA, psmouse->dev.keybit); | 435 | set_bit(BTN_EXTRA, psmouse->dev->keybit); |
| 437 | 436 | ||
| 438 | psmouse->vendor = "Kensington"; | 437 | psmouse->vendor = "Kensington"; |
| 439 | psmouse->name = "ThinkingMouse"; | 438 | psmouse->name = "ThinkingMouse"; |
| @@ -839,9 +838,9 @@ static void psmouse_disconnect(struct serio *serio) | |||
| 839 | 838 | ||
| 840 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 839 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
| 841 | 840 | ||
| 842 | input_unregister_device(&psmouse->dev); | ||
| 843 | serio_close(serio); | 841 | serio_close(serio); |
| 844 | serio_set_drvdata(serio, NULL); | 842 | serio_set_drvdata(serio, NULL); |
| 843 | input_unregister_device(psmouse->dev); | ||
| 845 | kfree(psmouse); | 844 | kfree(psmouse); |
| 846 | 845 | ||
| 847 | if (parent) | 846 | if (parent) |
| @@ -852,16 +851,14 @@ static void psmouse_disconnect(struct serio *serio) | |||
| 852 | 851 | ||
| 853 | static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) | 852 | static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) |
| 854 | { | 853 | { |
| 855 | memset(&psmouse->dev, 0, sizeof(struct input_dev)); | 854 | struct input_dev *input_dev = psmouse->dev; |
| 856 | 855 | ||
| 857 | init_input_dev(&psmouse->dev); | 856 | input_dev->private = psmouse; |
| 857 | input_dev->cdev.dev = &psmouse->ps2dev.serio->dev; | ||
| 858 | 858 | ||
| 859 | psmouse->dev.private = psmouse; | 859 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
| 860 | psmouse->dev.dev = &psmouse->ps2dev.serio->dev; | 860 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); |
| 861 | 861 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | |
| 862 | psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | ||
| 863 | psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | ||
| 864 | psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
| 865 | 862 | ||
| 866 | psmouse->set_rate = psmouse_set_rate; | 863 | psmouse->set_rate = psmouse_set_rate; |
| 867 | psmouse->set_resolution = psmouse_set_resolution; | 864 | psmouse->set_resolution = psmouse_set_resolution; |
| @@ -883,12 +880,12 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto | |||
| 883 | sprintf(psmouse->devname, "%s %s %s", | 880 | sprintf(psmouse->devname, "%s %s %s", |
| 884 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); | 881 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); |
| 885 | 882 | ||
| 886 | psmouse->dev.name = psmouse->devname; | 883 | input_dev->name = psmouse->devname; |
| 887 | psmouse->dev.phys = psmouse->phys; | 884 | input_dev->phys = psmouse->phys; |
| 888 | psmouse->dev.id.bustype = BUS_I8042; | 885 | input_dev->id.bustype = BUS_I8042; |
| 889 | psmouse->dev.id.vendor = 0x0002; | 886 | input_dev->id.vendor = 0x0002; |
| 890 | psmouse->dev.id.product = psmouse->type; | 887 | input_dev->id.product = psmouse->type; |
| 891 | psmouse->dev.id.version = psmouse->model; | 888 | input_dev->id.version = psmouse->model; |
| 892 | 889 | ||
| 893 | return 0; | 890 | return 0; |
| 894 | } | 891 | } |
| @@ -900,7 +897,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto | |||
| 900 | static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | 897 | static int psmouse_connect(struct serio *serio, struct serio_driver *drv) |
| 901 | { | 898 | { |
| 902 | struct psmouse *psmouse, *parent = NULL; | 899 | struct psmouse *psmouse, *parent = NULL; |
| 903 | int retval; | 900 | struct input_dev *input_dev; |
| 901 | int retval = -ENOMEM; | ||
| 904 | 902 | ||
| 905 | down(&psmouse_sem); | 903 | down(&psmouse_sem); |
| 906 | 904 | ||
| @@ -913,12 +911,13 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
| 913 | psmouse_deactivate(parent); | 911 | psmouse_deactivate(parent); |
| 914 | } | 912 | } |
| 915 | 913 | ||
| 916 | if (!(psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL))) { | 914 | psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); |
| 917 | retval = -ENOMEM; | 915 | input_dev = input_allocate_device(); |
| 916 | if (!psmouse || !input_dev) | ||
| 918 | goto out; | 917 | goto out; |
| 919 | } | ||
| 920 | 918 | ||
| 921 | ps2_init(&psmouse->ps2dev, serio); | 919 | ps2_init(&psmouse->ps2dev, serio); |
| 920 | psmouse->dev = input_dev; | ||
| 922 | sprintf(psmouse->phys, "%s/input0", serio->phys); | 921 | sprintf(psmouse->phys, "%s/input0", serio->phys); |
| 923 | 922 | ||
| 924 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 923 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
| @@ -926,16 +925,11 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
| 926 | serio_set_drvdata(serio, psmouse); | 925 | serio_set_drvdata(serio, psmouse); |
| 927 | 926 | ||
| 928 | retval = serio_open(serio, drv); | 927 | retval = serio_open(serio, drv); |
| 929 | if (retval) { | 928 | if (retval) |
| 930 | serio_set_drvdata(serio, NULL); | ||
| 931 | kfree(psmouse); | ||
| 932 | goto out; | 929 | goto out; |
| 933 | } | ||
| 934 | 930 | ||
| 935 | if (psmouse_probe(psmouse) < 0) { | 931 | if (psmouse_probe(psmouse) < 0) { |
| 936 | serio_close(serio); | 932 | serio_close(serio); |
| 937 | serio_set_drvdata(serio, NULL); | ||
| 938 | kfree(psmouse); | ||
| 939 | retval = -ENODEV; | 933 | retval = -ENODEV; |
| 940 | goto out; | 934 | goto out; |
| 941 | } | 935 | } |
| @@ -947,13 +941,11 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
| 947 | 941 | ||
| 948 | psmouse_switch_protocol(psmouse, NULL); | 942 | psmouse_switch_protocol(psmouse, NULL); |
| 949 | 943 | ||
| 950 | input_register_device(&psmouse->dev); | ||
| 951 | printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); | ||
| 952 | |||
| 953 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 944 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
| 954 | |||
| 955 | psmouse_initialize(psmouse); | 945 | psmouse_initialize(psmouse); |
| 956 | 946 | ||
| 947 | input_register_device(psmouse->dev); | ||
| 948 | |||
| 957 | if (parent && parent->pt_activate) | 949 | if (parent && parent->pt_activate) |
| 958 | parent->pt_activate(parent); | 950 | parent->pt_activate(parent); |
| 959 | 951 | ||
| @@ -964,6 +956,12 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
| 964 | retval = 0; | 956 | retval = 0; |
| 965 | 957 | ||
| 966 | out: | 958 | out: |
| 959 | if (retval) { | ||
| 960 | serio_set_drvdata(serio, NULL); | ||
| 961 | input_free_device(input_dev); | ||
| 962 | kfree(psmouse); | ||
| 963 | } | ||
| 964 | |||
| 967 | /* If this is a pass-through port the parent needs to be re-activated */ | 965 | /* If this is a pass-through port the parent needs to be re-activated */ |
| 968 | if (parent) | 966 | if (parent) |
| 969 | psmouse_activate(parent); | 967 | psmouse_activate(parent); |
| @@ -1161,6 +1159,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
| 1161 | { | 1159 | { |
| 1162 | struct serio *serio = psmouse->ps2dev.serio; | 1160 | struct serio *serio = psmouse->ps2dev.serio; |
| 1163 | struct psmouse *parent = NULL; | 1161 | struct psmouse *parent = NULL; |
| 1162 | struct input_dev *new_dev; | ||
| 1164 | struct psmouse_protocol *proto; | 1163 | struct psmouse_protocol *proto; |
| 1165 | int retry = 0; | 1164 | int retry = 0; |
| 1166 | 1165 | ||
| @@ -1170,9 +1169,13 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
| 1170 | if (psmouse->type == proto->type) | 1169 | if (psmouse->type == proto->type) |
| 1171 | return count; | 1170 | return count; |
| 1172 | 1171 | ||
| 1172 | if (!(new_dev = input_allocate_device())) | ||
| 1173 | return -ENOMEM; | ||
| 1174 | |||
| 1173 | while (serio->child) { | 1175 | while (serio->child) { |
| 1174 | if (++retry > 3) { | 1176 | if (++retry > 3) { |
| 1175 | printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n"); | 1177 | printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n"); |
| 1178 | input_free_device(new_dev); | ||
| 1176 | return -EIO; | 1179 | return -EIO; |
| 1177 | } | 1180 | } |
| 1178 | 1181 | ||
| @@ -1182,11 +1185,15 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
| 1182 | serio_pin_driver_uninterruptible(serio); | 1185 | serio_pin_driver_uninterruptible(serio); |
| 1183 | down(&psmouse_sem); | 1186 | down(&psmouse_sem); |
| 1184 | 1187 | ||
| 1185 | if (serio->drv != &psmouse_drv) | 1188 | if (serio->drv != &psmouse_drv) { |
| 1189 | input_free_device(new_dev); | ||
| 1186 | return -ENODEV; | 1190 | return -ENODEV; |
| 1191 | } | ||
| 1187 | 1192 | ||
| 1188 | if (psmouse->type == proto->type) | 1193 | if (psmouse->type == proto->type) { |
| 1194 | input_free_device(new_dev); | ||
| 1189 | return count; /* switched by other thread */ | 1195 | return count; /* switched by other thread */ |
| 1196 | } | ||
| 1190 | } | 1197 | } |
| 1191 | 1198 | ||
| 1192 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 1199 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
| @@ -1199,8 +1206,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
| 1199 | psmouse->disconnect(psmouse); | 1206 | psmouse->disconnect(psmouse); |
| 1200 | 1207 | ||
| 1201 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 1208 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
| 1202 | input_unregister_device(&psmouse->dev); | 1209 | input_unregister_device(psmouse->dev); |
| 1203 | 1210 | ||
| 1211 | psmouse->dev = new_dev; | ||
| 1204 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 1212 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
| 1205 | 1213 | ||
| 1206 | if (psmouse_switch_protocol(psmouse, proto) < 0) { | 1214 | if (psmouse_switch_protocol(psmouse, proto) < 0) { |
| @@ -1212,8 +1220,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
| 1212 | psmouse_initialize(psmouse); | 1220 | psmouse_initialize(psmouse); |
| 1213 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1221 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
| 1214 | 1222 | ||
| 1215 | input_register_device(&psmouse->dev); | 1223 | input_register_device(psmouse->dev); |
| 1216 | printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); | ||
| 1217 | 1224 | ||
| 1218 | if (parent && parent->pt_activate) | 1225 | if (parent && parent->pt_activate) |
| 1219 | parent->pt_activate(parent); | 1226 | parent->pt_activate(parent); |
