aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-09-29 18:52:59 -0400
committerJiri Kosina <jkosina@suse.cz>2015-09-30 04:07:09 -0400
commitb2c68a2f1bab3e3d3bf4ab2b5fcd94cd37f61b41 (patch)
treeb8d5fbadb77568922c5f804777bbb2aa998d9a6d
parent0678072755b6672b19ee0fd42748a003912fca09 (diff)
HID: hid-input: allow input_configured callback return errors
When configuring input device via input_configured callback we may encounter errors (for example input_mt_init_slots() may fail). Instead of continuing with half-initialized input device let's allow driver indicate failures. Signed-off-by: Jaikumar Ganesh <jaikumarg@android.com> Signed-off-by: Arve Hjønnevåg <arve@android.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Reviewed-by: David Herrmann <dh.herrmann@gmail.com> Acked-by: Nikolai Kondrashov <Nikolai.Kondrashov@redhat.com> Acked-by: Andrew Duggan <aduggan@synaptics.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-appleir.c4
-rw-r--r--drivers/hid/hid-elo.c4
-rw-r--r--drivers/hid/hid-input.c10
-rw-r--r--drivers/hid/hid-lenovo.c4
-rw-r--r--drivers/hid/hid-logitech-hidpp.c4
-rw-r--r--drivers/hid/hid-magicmouse.c8
-rw-r--r--drivers/hid/hid-multitouch.c20
-rw-r--r--drivers/hid/hid-ntrig.c6
-rw-r--r--drivers/hid/hid-rmi.c11
-rw-r--r--drivers/hid/hid-sony.c13
-rw-r--r--drivers/hid/hid-uclogic.c6
-rw-r--r--include/linux/hid.h4
12 files changed, 66 insertions, 28 deletions
diff --git a/drivers/hid/hid-appleir.c b/drivers/hid/hid-appleir.c
index 0e6a42d37eb6..07cbc70f00e7 100644
--- a/drivers/hid/hid-appleir.c
+++ b/drivers/hid/hid-appleir.c
@@ -256,7 +256,7 @@ out:
256 return 0; 256 return 0;
257} 257}
258 258
259static void appleir_input_configured(struct hid_device *hid, 259static int appleir_input_configured(struct hid_device *hid,
260 struct hid_input *hidinput) 260 struct hid_input *hidinput)
261{ 261{
262 struct input_dev *input_dev = hidinput->input; 262 struct input_dev *input_dev = hidinput->input;
@@ -275,6 +275,8 @@ static void appleir_input_configured(struct hid_device *hid,
275 for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++) 275 for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++)
276 set_bit(appleir->keymap[i], input_dev->keybit); 276 set_bit(appleir->keymap[i], input_dev->keybit);
277 clear_bit(KEY_RESERVED, input_dev->keybit); 277 clear_bit(KEY_RESERVED, input_dev->keybit);
278
279 return 0;
278} 280}
279 281
280static int appleir_input_mapping(struct hid_device *hid, 282static int appleir_input_mapping(struct hid_device *hid,
diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c
index 4e49462870ab..aad8c162a825 100644
--- a/drivers/hid/hid-elo.c
+++ b/drivers/hid/hid-elo.c
@@ -37,7 +37,7 @@ static bool use_fw_quirk = true;
37module_param(use_fw_quirk, bool, S_IRUGO); 37module_param(use_fw_quirk, bool, S_IRUGO);
38MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)"); 38MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)");
39 39
40static void elo_input_configured(struct hid_device *hdev, 40static int elo_input_configured(struct hid_device *hdev,
41 struct hid_input *hidinput) 41 struct hid_input *hidinput)
42{ 42{
43 struct input_dev *input = hidinput->input; 43 struct input_dev *input = hidinput->input;
@@ -45,6 +45,8 @@ static void elo_input_configured(struct hid_device *hdev,
45 set_bit(BTN_TOUCH, input->keybit); 45 set_bit(BTN_TOUCH, input->keybit);
46 set_bit(ABS_PRESSURE, input->absbit); 46 set_bit(ABS_PRESSURE, input->absbit);
47 input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0); 47 input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0);
48
49 return 0;
48} 50}
49 51
50static void elo_process_data(struct input_dev *input, const u8 *data, int size) 52static void elo_process_data(struct input_dev *input, const u8 *data, int size)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 53aeaf6252c7..2ba6bf69b7d0 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1510,8 +1510,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1510 * UGCI) cram a lot of unrelated inputs into the 1510 * UGCI) cram a lot of unrelated inputs into the
1511 * same interface. */ 1511 * same interface. */
1512 hidinput->report = report; 1512 hidinput->report = report;
1513 if (drv->input_configured) 1513 if (drv->input_configured &&
1514 drv->input_configured(hid, hidinput); 1514 drv->input_configured(hid, hidinput))
1515 goto out_cleanup;
1515 if (input_register_device(hidinput->input)) 1516 if (input_register_device(hidinput->input))
1516 goto out_cleanup; 1517 goto out_cleanup;
1517 hidinput = NULL; 1518 hidinput = NULL;
@@ -1532,8 +1533,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
1532 } 1533 }
1533 1534
1534 if (hidinput) { 1535 if (hidinput) {
1535 if (drv->input_configured) 1536 if (drv->input_configured &&
1536 drv->input_configured(hid, hidinput); 1537 drv->input_configured(hid, hidinput))
1538 goto out_cleanup;
1537 if (input_register_device(hidinput->input)) 1539 if (input_register_device(hidinput->input))
1538 goto out_cleanup; 1540 goto out_cleanup;
1539 } 1541 }
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index e4bc6cb6d7fa..8979f1fd5208 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -848,7 +848,7 @@ static void lenovo_remove(struct hid_device *hdev)
848 hid_hw_stop(hdev); 848 hid_hw_stop(hdev);
849} 849}
850 850
851static void lenovo_input_configured(struct hid_device *hdev, 851static int lenovo_input_configured(struct hid_device *hdev,
852 struct hid_input *hi) 852 struct hid_input *hi)
853{ 853{
854 switch (hdev->product) { 854 switch (hdev->product) {
@@ -863,6 +863,8 @@ static void lenovo_input_configured(struct hid_device *hdev,
863 } 863 }
864 break; 864 break;
865 } 865 }
866
867 return 0;
866} 868}
867 869
868 870
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 484196459305..a25f562f2d7b 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -1160,13 +1160,15 @@ static void hidpp_populate_input(struct hidpp_device *hidpp,
1160 m560_populate_input(hidpp, input, origin_is_hid_core); 1160 m560_populate_input(hidpp, input, origin_is_hid_core);
1161} 1161}
1162 1162
1163static void hidpp_input_configured(struct hid_device *hdev, 1163static int hidpp_input_configured(struct hid_device *hdev,
1164 struct hid_input *hidinput) 1164 struct hid_input *hidinput)
1165{ 1165{
1166 struct hidpp_device *hidpp = hid_get_drvdata(hdev); 1166 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1167 struct input_dev *input = hidinput->input; 1167 struct input_dev *input = hidinput->input;
1168 1168
1169 hidpp_populate_input(hidpp, input, true); 1169 hidpp_populate_input(hidpp, input, true);
1170
1171 return 0;
1170} 1172}
1171 1173
1172static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, 1174static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 29a74c1efcb8..d6fa496d0ca2 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -471,18 +471,22 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
471 return 0; 471 return 0;
472} 472}
473 473
474static void magicmouse_input_configured(struct hid_device *hdev, 474static int magicmouse_input_configured(struct hid_device *hdev,
475 struct hid_input *hi) 475 struct hid_input *hi)
476 476
477{ 477{
478 struct magicmouse_sc *msc = hid_get_drvdata(hdev); 478 struct magicmouse_sc *msc = hid_get_drvdata(hdev);
479 int ret;
479 480
480 int ret = magicmouse_setup_input(msc->input, hdev); 481 ret = magicmouse_setup_input(msc->input, hdev);
481 if (ret) { 482 if (ret) {
482 hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); 483 hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
483 /* clean msc->input to notify probe() of the failure */ 484 /* clean msc->input to notify probe() of the failure */
484 msc->input = NULL; 485 msc->input = NULL;
486 return ret;
485 } 487 }
488
489 return 0;
486} 490}
487 491
488 492
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 426b2f1a3450..2ed42d8f805b 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -725,12 +725,13 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
725 mt_sync_frame(td, report->field[0]->hidinput->input); 725 mt_sync_frame(td, report->field[0]->hidinput->input);
726} 726}
727 727
728static void mt_touch_input_configured(struct hid_device *hdev, 728static int mt_touch_input_configured(struct hid_device *hdev,
729 struct hid_input *hi) 729 struct hid_input *hi)
730{ 730{
731 struct mt_device *td = hid_get_drvdata(hdev); 731 struct mt_device *td = hid_get_drvdata(hdev);
732 struct mt_class *cls = &td->mtclass; 732 struct mt_class *cls = &td->mtclass;
733 struct input_dev *input = hi->input; 733 struct input_dev *input = hi->input;
734 int ret;
734 735
735 if (!td->maxcontacts) 736 if (!td->maxcontacts)
736 td->maxcontacts = MT_DEFAULT_MAXCONTACT; 737 td->maxcontacts = MT_DEFAULT_MAXCONTACT;
@@ -752,9 +753,12 @@ static void mt_touch_input_configured(struct hid_device *hdev,
752 if (td->is_buttonpad) 753 if (td->is_buttonpad)
753 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 754 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
754 755
755 input_mt_init_slots(input, td->maxcontacts, td->mt_flags); 756 ret = input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
757 if (ret)
758 return ret;
756 759
757 td->mt_flags = 0; 760 td->mt_flags = 0;
761 return 0;
758} 762}
759 763
760static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, 764static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -930,15 +934,19 @@ static void mt_post_parse(struct mt_device *td)
930 cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; 934 cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
931} 935}
932 936
933static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) 937static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
934{ 938{
935 struct mt_device *td = hid_get_drvdata(hdev); 939 struct mt_device *td = hid_get_drvdata(hdev);
936 char *name; 940 char *name;
937 const char *suffix = NULL; 941 const char *suffix = NULL;
938 struct hid_field *field = hi->report->field[0]; 942 struct hid_field *field = hi->report->field[0];
943 int ret;
939 944
940 if (hi->report->id == td->mt_report_id) 945 if (hi->report->id == td->mt_report_id) {
941 mt_touch_input_configured(hdev, hi); 946 ret = mt_touch_input_configured(hdev, hi);
947 if (ret)
948 return ret;
949 }
942 950
943 /* 951 /*
944 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN" 952 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
@@ -989,6 +997,8 @@ static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
989 hi->input->name = name; 997 hi->input->name = name;
990 } 998 }
991 } 999 }
1000
1001 return 0;
992} 1002}
993 1003
994static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 1004static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 600f2075512f..756d1ef9bd99 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -859,14 +859,14 @@ not_claimed_input:
859 return 1; 859 return 1;
860} 860}
861 861
862static void ntrig_input_configured(struct hid_device *hid, 862static int ntrig_input_configured(struct hid_device *hid,
863 struct hid_input *hidinput) 863 struct hid_input *hidinput)
864 864
865{ 865{
866 struct input_dev *input = hidinput->input; 866 struct input_dev *input = hidinput->input;
867 867
868 if (hidinput->report->maxfield < 1) 868 if (hidinput->report->maxfield < 1)
869 return; 869 return 0;
870 870
871 switch (hidinput->report->field[0]->application) { 871 switch (hidinput->report->field[0]->application) {
872 case HID_DG_PEN: 872 case HID_DG_PEN:
@@ -890,6 +890,8 @@ static void ntrig_input_configured(struct hid_device *hid,
890 "N-Trig MultiTouch"; 890 "N-Trig MultiTouch";
891 break; 891 break;
892 } 892 }
893
894 return 0;
893} 895}
894 896
895static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) 897static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index 2c148129beb2..67cd059a8f46 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -1173,7 +1173,7 @@ static int rmi_populate(struct hid_device *hdev)
1173 return 0; 1173 return 0;
1174} 1174}
1175 1175
1176static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi) 1176static int rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
1177{ 1177{
1178 struct rmi_data *data = hid_get_drvdata(hdev); 1178 struct rmi_data *data = hid_get_drvdata(hdev);
1179 struct input_dev *input = hi->input; 1179 struct input_dev *input = hi->input;
@@ -1185,10 +1185,10 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
1185 hid_dbg(hdev, "Opening low level driver\n"); 1185 hid_dbg(hdev, "Opening low level driver\n");
1186 ret = hid_hw_open(hdev); 1186 ret = hid_hw_open(hdev);
1187 if (ret) 1187 if (ret)
1188 return; 1188 return ret;
1189 1189
1190 if (!(data->device_flags & RMI_DEVICE)) 1190 if (!(data->device_flags & RMI_DEVICE))
1191 return; 1191 return 0;
1192 1192
1193 /* Allow incoming hid reports */ 1193 /* Allow incoming hid reports */
1194 hid_device_io_start(hdev); 1194 hid_device_io_start(hdev);
@@ -1228,7 +1228,9 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
1228 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0); 1228 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0);
1229 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0); 1229 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0);
1230 1230
1231 input_mt_init_slots(input, data->max_fingers, INPUT_MT_POINTER); 1231 ret = input_mt_init_slots(input, data->max_fingers, INPUT_MT_POINTER);
1232 if (ret < 0)
1233 goto exit;
1232 1234
1233 if (data->button_count) { 1235 if (data->button_count) {
1234 __set_bit(EV_KEY, input->evbit); 1236 __set_bit(EV_KEY, input->evbit);
@@ -1244,6 +1246,7 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
1244exit: 1246exit:
1245 hid_device_io_stop(hdev); 1247 hid_device_io_stop(hdev);
1246 hid_hw_close(hdev); 1248 hid_hw_close(hdev);
1249 return ret;
1247} 1250}
1248 1251
1249static int rmi_input_mapping(struct hid_device *hdev, 1252static int rmi_input_mapping(struct hid_device *hdev,
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 661f94f8ab8b..774cd2210566 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1360,20 +1360,27 @@ static int sony_register_touchpad(struct hid_input *hi, int touch_count,
1360 return 0; 1360 return 0;
1361} 1361}
1362 1362
1363static void sony_input_configured(struct hid_device *hdev, 1363static int sony_input_configured(struct hid_device *hdev,
1364 struct hid_input *hidinput) 1364 struct hid_input *hidinput)
1365{ 1365{
1366 struct sony_sc *sc = hid_get_drvdata(hdev); 1366 struct sony_sc *sc = hid_get_drvdata(hdev);
1367 int ret;
1367 1368
1368 /* 1369 /*
1369 * The Dualshock 4 touchpad supports 2 touches and has a 1370 * The Dualshock 4 touchpad supports 2 touches and has a
1370 * resolution of 1920x942 (44.86 dots/mm). 1371 * resolution of 1920x942 (44.86 dots/mm).
1371 */ 1372 */
1372 if (sc->quirks & DUALSHOCK4_CONTROLLER) { 1373 if (sc->quirks & DUALSHOCK4_CONTROLLER) {
1373 if (sony_register_touchpad(hidinput, 2, 1920, 942) != 0) 1374 ret = sony_register_touchpad(hidinput, 2, 1920, 942);
1375 if (ret) {
1374 hid_err(sc->hdev, 1376 hid_err(sc->hdev,
1375 "Unable to initialize multi-touch slots\n"); 1377 "Unable to initialize multi-touch slots: %d\n",
1378 ret);
1379 return ret;
1380 }
1376 } 1381 }
1382
1383 return 0;
1377} 1384}
1378 1385
1379/* 1386/*
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c
index b905d501e752..85ac43517e3f 100644
--- a/drivers/hid/hid-uclogic.c
+++ b/drivers/hid/hid-uclogic.c
@@ -731,7 +731,7 @@ static int uclogic_input_mapping(struct hid_device *hdev, struct hid_input *hi,
731 return 0; 731 return 0;
732} 732}
733 733
734static void uclogic_input_configured(struct hid_device *hdev, 734static int uclogic_input_configured(struct hid_device *hdev,
735 struct hid_input *hi) 735 struct hid_input *hi)
736{ 736{
737 char *name; 737 char *name;
@@ -741,7 +741,7 @@ static void uclogic_input_configured(struct hid_device *hdev,
741 741
742 /* no report associated (HID_QUIRK_MULTI_INPUT not set) */ 742 /* no report associated (HID_QUIRK_MULTI_INPUT not set) */
743 if (!hi->report) 743 if (!hi->report)
744 return; 744 return 0;
745 745
746 field = hi->report->field[0]; 746 field = hi->report->field[0];
747 747
@@ -774,6 +774,8 @@ static void uclogic_input_configured(struct hid_device *hdev,
774 hi->input->name = name; 774 hi->input->name = name;
775 } 775 }
776 } 776 }
777
778 return 0;
777} 779}
778 780
779/** 781/**
diff --git a/include/linux/hid.h b/include/linux/hid.h
index f17980de2662..251a1d382e23 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -698,8 +698,8 @@ struct hid_driver {
698 int (*input_mapped)(struct hid_device *hdev, 698 int (*input_mapped)(struct hid_device *hdev,
699 struct hid_input *hidinput, struct hid_field *field, 699 struct hid_input *hidinput, struct hid_field *field,
700 struct hid_usage *usage, unsigned long **bit, int *max); 700 struct hid_usage *usage, unsigned long **bit, int *max);
701 void (*input_configured)(struct hid_device *hdev, 701 int (*input_configured)(struct hid_device *hdev,
702 struct hid_input *hidinput); 702 struct hid_input *hidinput);
703 void (*feature_mapping)(struct hid_device *hdev, 703 void (*feature_mapping)(struct hid_device *hdev,
704 struct hid_field *field, 704 struct hid_field *field,
705 struct hid_usage *usage); 705 struct hid_usage *usage);