aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/psmouse-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
-rw-r--r--drivers/input/mouse/psmouse-base.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 6f9b2c7cc9c2..9144df65e703 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -1102,7 +1102,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
1102{ 1102{
1103 struct psmouse *psmouse, *parent = NULL; 1103 struct psmouse *psmouse, *parent = NULL;
1104 struct input_dev *input_dev; 1104 struct input_dev *input_dev;
1105 int retval = -ENOMEM; 1105 int retval = 0, error = -ENOMEM;
1106 1106
1107 mutex_lock(&psmouse_mutex); 1107 mutex_lock(&psmouse_mutex);
1108 1108
@@ -1118,7 +1118,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
1118 psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); 1118 psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
1119 input_dev = input_allocate_device(); 1119 input_dev = input_allocate_device();
1120 if (!psmouse || !input_dev) 1120 if (!psmouse || !input_dev)
1121 goto out; 1121 goto err_free;
1122 1122
1123 ps2_init(&psmouse->ps2dev, serio); 1123 ps2_init(&psmouse->ps2dev, serio);
1124 INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); 1124 INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);
@@ -1129,14 +1129,13 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
1129 1129
1130 serio_set_drvdata(serio, psmouse); 1130 serio_set_drvdata(serio, psmouse);
1131 1131
1132 retval = serio_open(serio, drv); 1132 error = serio_open(serio, drv);
1133 if (retval) 1133 if (error)
1134 goto out; 1134 goto err_clear_drvdata;
1135 1135
1136 if (psmouse_probe(psmouse) < 0) { 1136 if (psmouse_probe(psmouse) < 0) {
1137 serio_close(serio); 1137 error = -ENODEV;
1138 retval = -ENODEV; 1138 goto err_close_serio;
1139 goto out;
1140 } 1139 }
1141 1140
1142 psmouse->rate = psmouse_rate; 1141 psmouse->rate = psmouse_rate;
@@ -1150,30 +1149,44 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
1150 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 1149 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
1151 psmouse_initialize(psmouse); 1150 psmouse_initialize(psmouse);
1152 1151
1153 input_register_device(psmouse->dev); 1152 error = input_register_device(psmouse->dev);
1153 if (error)
1154 goto err_protocol_disconnect;
1154 1155
1155 if (parent && parent->pt_activate) 1156 if (parent && parent->pt_activate)
1156 parent->pt_activate(parent); 1157 parent->pt_activate(parent);
1157 1158
1158 sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group); 1159 error = sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group);
1160 if (error)
1161 goto err_pt_deactivate;
1159 1162
1160 psmouse_activate(psmouse); 1163 psmouse_activate(psmouse);
1161 1164
1162 retval = 0; 1165 out:
1163
1164out:
1165 if (retval) {
1166 serio_set_drvdata(serio, NULL);
1167 input_free_device(input_dev);
1168 kfree(psmouse);
1169 }
1170
1171 /* If this is a pass-through port the parent needs to be re-activated */ 1166 /* If this is a pass-through port the parent needs to be re-activated */
1172 if (parent) 1167 if (parent)
1173 psmouse_activate(parent); 1168 psmouse_activate(parent);
1174 1169
1175 mutex_unlock(&psmouse_mutex); 1170 mutex_unlock(&psmouse_mutex);
1176 return retval; 1171 return retval;
1172
1173 err_pt_deactivate:
1174 if (parent && parent->pt_deactivate)
1175 parent->pt_deactivate(parent);
1176 err_protocol_disconnect:
1177 if (psmouse->disconnect)
1178 psmouse->disconnect(psmouse);
1179 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
1180 err_close_serio:
1181 serio_close(serio);
1182 err_clear_drvdata:
1183 serio_set_drvdata(serio, NULL);
1184 err_free:
1185 input_free_device(input_dev);
1186 kfree(psmouse);
1187
1188 retval = error;
1189 goto out;
1177} 1190}
1178 1191
1179 1192
@@ -1365,17 +1378,20 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
1365{ 1378{
1366 struct serio *serio = psmouse->ps2dev.serio; 1379 struct serio *serio = psmouse->ps2dev.serio;
1367 struct psmouse *parent = NULL; 1380 struct psmouse *parent = NULL;
1368 struct input_dev *new_dev; 1381 struct input_dev *old_dev, *new_dev;
1369 const struct psmouse_protocol *proto; 1382 const struct psmouse_protocol *proto, *old_proto;
1383 int error;
1370 int retry = 0; 1384 int retry = 0;
1371 1385
1372 if (!(proto = psmouse_protocol_by_name(buf, count))) 1386 proto = psmouse_protocol_by_name(buf, count);
1387 if (!proto)
1373 return -EINVAL; 1388 return -EINVAL;
1374 1389
1375 if (psmouse->type == proto->type) 1390 if (psmouse->type == proto->type)
1376 return count; 1391 return count;
1377 1392
1378 if (!(new_dev = input_allocate_device())) 1393 new_dev = input_allocate_device();
1394 if (!new_dev)
1379 return -ENOMEM; 1395 return -ENOMEM;
1380 1396
1381 while (serio->child) { 1397 while (serio->child) {
@@ -1408,11 +1424,13 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
1408 parent->pt_deactivate(parent); 1424 parent->pt_deactivate(parent);
1409 } 1425 }
1410 1426
1427 old_dev = psmouse->dev;
1428 old_proto = psmouse_protocol_by_type(psmouse->type);
1429
1411 if (psmouse->disconnect) 1430 if (psmouse->disconnect)
1412 psmouse->disconnect(psmouse); 1431 psmouse->disconnect(psmouse);
1413 1432
1414 psmouse_set_state(psmouse, PSMOUSE_IGNORE); 1433 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
1415 input_unregister_device(psmouse->dev);
1416 1434
1417 psmouse->dev = new_dev; 1435 psmouse->dev = new_dev;
1418 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); 1436 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
@@ -1426,7 +1444,23 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
1426 psmouse_initialize(psmouse); 1444 psmouse_initialize(psmouse);
1427 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 1445 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
1428 1446
1429 input_register_device(psmouse->dev); 1447 error = input_register_device(psmouse->dev);
1448 if (error) {
1449 if (psmouse->disconnect)
1450 psmouse->disconnect(psmouse);
1451
1452 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
1453 input_free_device(new_dev);
1454 psmouse->dev = old_dev;
1455 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
1456 psmouse_switch_protocol(psmouse, old_proto);
1457 psmouse_initialize(psmouse);
1458 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
1459
1460 return error;
1461 }
1462
1463 input_unregister_device(old_dev);
1430 1464
1431 if (parent && parent->pt_activate) 1465 if (parent && parent->pt_activate)
1432 parent->pt_activate(parent); 1466 parent->pt_activate(parent);