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); |