Skip to content

Commit b2c68a2

Browse files
dtorJiri Kosina
authored andcommitted
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 <[email protected]> Signed-off-by: Arve Hjønnevåg <[email protected]> Reviewed-by: Benjamin Tissoires <[email protected]> Reviewed-by: David Herrmann <[email protected]> Acked-by: Nikolai Kondrashov <[email protected]> Acked-by: Andrew Duggan <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 0678072 commit b2c68a2

File tree

12 files changed

+66
-28
lines changed

12 files changed

+66
-28
lines changed

drivers/hid/hid-appleir.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
256256
return 0;
257257
}
258258

259-
static void appleir_input_configured(struct hid_device *hid,
259+
static int appleir_input_configured(struct hid_device *hid,
260260
struct hid_input *hidinput)
261261
{
262262
struct input_dev *input_dev = hidinput->input;
@@ -275,6 +275,8 @@ static void appleir_input_configured(struct hid_device *hid,
275275
for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++)
276276
set_bit(appleir->keymap[i], input_dev->keybit);
277277
clear_bit(KEY_RESERVED, input_dev->keybit);
278+
279+
return 0;
278280
}
279281

280282
static int appleir_input_mapping(struct hid_device *hid,

drivers/hid/hid-elo.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@ static bool use_fw_quirk = true;
3737
module_param(use_fw_quirk, bool, S_IRUGO);
3838
MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)");
3939

40-
static void elo_input_configured(struct hid_device *hdev,
40+
static int elo_input_configured(struct hid_device *hdev,
4141
struct hid_input *hidinput)
4242
{
4343
struct input_dev *input = hidinput->input;
4444

4545
set_bit(BTN_TOUCH, input->keybit);
4646
set_bit(ABS_PRESSURE, input->absbit);
4747
input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0);
48+
49+
return 0;
4850
}
4951

5052
static void elo_process_data(struct input_dev *input, const u8 *data, int size)

drivers/hid/hid-input.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,8 +1510,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
15101510
* UGCI) cram a lot of unrelated inputs into the
15111511
* same interface. */
15121512
hidinput->report = report;
1513-
if (drv->input_configured)
1514-
drv->input_configured(hid, hidinput);
1513+
if (drv->input_configured &&
1514+
drv->input_configured(hid, hidinput))
1515+
goto out_cleanup;
15151516
if (input_register_device(hidinput->input))
15161517
goto out_cleanup;
15171518
hidinput = NULL;
@@ -1532,8 +1533,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
15321533
}
15331534

15341535
if (hidinput) {
1535-
if (drv->input_configured)
1536-
drv->input_configured(hid, hidinput);
1536+
if (drv->input_configured &&
1537+
drv->input_configured(hid, hidinput))
1538+
goto out_cleanup;
15371539
if (input_register_device(hidinput->input))
15381540
goto out_cleanup;
15391541
}

drivers/hid/hid-lenovo.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ static void lenovo_remove(struct hid_device *hdev)
848848
hid_hw_stop(hdev);
849849
}
850850

851-
static void lenovo_input_configured(struct hid_device *hdev,
851+
static int lenovo_input_configured(struct hid_device *hdev,
852852
struct hid_input *hi)
853853
{
854854
switch (hdev->product) {
@@ -863,6 +863,8 @@ static void lenovo_input_configured(struct hid_device *hdev,
863863
}
864864
break;
865865
}
866+
867+
return 0;
866868
}
867869

868870

drivers/hid/hid-logitech-hidpp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,13 +1160,15 @@ static void hidpp_populate_input(struct hidpp_device *hidpp,
11601160
m560_populate_input(hidpp, input, origin_is_hid_core);
11611161
}
11621162

1163-
static void hidpp_input_configured(struct hid_device *hdev,
1163+
static int hidpp_input_configured(struct hid_device *hdev,
11641164
struct hid_input *hidinput)
11651165
{
11661166
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
11671167
struct input_dev *input = hidinput->input;
11681168

11691169
hidpp_populate_input(hidpp, input, true);
1170+
1171+
return 0;
11701172
}
11711173

11721174
static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,

drivers/hid/hid-magicmouse.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,18 +471,22 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
471471
return 0;
472472
}
473473

474-
static void magicmouse_input_configured(struct hid_device *hdev,
474+
static int magicmouse_input_configured(struct hid_device *hdev,
475475
struct hid_input *hi)
476476

477477
{
478478
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
479+
int ret;
479480

480-
int ret = magicmouse_setup_input(msc->input, hdev);
481+
ret = magicmouse_setup_input(msc->input, hdev);
481482
if (ret) {
482483
hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
483484
/* clean msc->input to notify probe() of the failure */
484485
msc->input = NULL;
486+
return ret;
485487
}
488+
489+
return 0;
486490
}
487491

488492

drivers/hid/hid-multitouch.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -725,12 +725,13 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
725725
mt_sync_frame(td, report->field[0]->hidinput->input);
726726
}
727727

728-
static void mt_touch_input_configured(struct hid_device *hdev,
728+
static int mt_touch_input_configured(struct hid_device *hdev,
729729
struct hid_input *hi)
730730
{
731731
struct mt_device *td = hid_get_drvdata(hdev);
732732
struct mt_class *cls = &td->mtclass;
733733
struct input_dev *input = hi->input;
734+
int ret;
734735

735736
if (!td->maxcontacts)
736737
td->maxcontacts = MT_DEFAULT_MAXCONTACT;
@@ -752,9 +753,12 @@ static void mt_touch_input_configured(struct hid_device *hdev,
752753
if (td->is_buttonpad)
753754
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
754755

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

757760
td->mt_flags = 0;
761+
return 0;
758762
}
759763

760764
static 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)
930934
cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
931935
}
932936

933-
static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
937+
static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
934938
{
935939
struct mt_device *td = hid_get_drvdata(hdev);
936940
char *name;
937941
const char *suffix = NULL;
938942
struct hid_field *field = hi->report->field[0];
943+
int ret;
939944

940-
if (hi->report->id == td->mt_report_id)
941-
mt_touch_input_configured(hdev, hi);
945+
if (hi->report->id == td->mt_report_id) {
946+
ret = mt_touch_input_configured(hdev, hi);
947+
if (ret)
948+
return ret;
949+
}
942950

943951
/*
944952
* 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)
989997
hi->input->name = name;
990998
}
991999
}
1000+
1001+
return 0;
9921002
}
9931003

9941004
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)

drivers/hid/hid-ntrig.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,14 +859,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
859859
return 1;
860860
}
861861

862-
static void ntrig_input_configured(struct hid_device *hid,
862+
static int ntrig_input_configured(struct hid_device *hid,
863863
struct hid_input *hidinput)
864864

865865
{
866866
struct input_dev *input = hidinput->input;
867867

868868
if (hidinput->report->maxfield < 1)
869-
return;
869+
return 0;
870870

871871
switch (hidinput->report->field[0]->application) {
872872
case HID_DG_PEN:
@@ -890,6 +890,8 @@ static void ntrig_input_configured(struct hid_device *hid,
890890
"N-Trig MultiTouch";
891891
break;
892892
}
893+
894+
return 0;
893895
}
894896

895897
static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)

drivers/hid/hid-rmi.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ static int rmi_populate(struct hid_device *hdev)
11731173
return 0;
11741174
}
11751175

1176-
static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
1176+
static int rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
11771177
{
11781178
struct rmi_data *data = hid_get_drvdata(hdev);
11791179
struct input_dev *input = hi->input;
@@ -1185,10 +1185,10 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
11851185
hid_dbg(hdev, "Opening low level driver\n");
11861186
ret = hid_hw_open(hdev);
11871187
if (ret)
1188-
return;
1188+
return ret;
11891189

11901190
if (!(data->device_flags & RMI_DEVICE))
1191-
return;
1191+
return 0;
11921192

11931193
/* Allow incoming hid reports */
11941194
hid_device_io_start(hdev);
@@ -1228,7 +1228,9 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
12281228
input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0);
12291229
input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0);
12301230

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

12331235
if (data->button_count) {
12341236
__set_bit(EV_KEY, input->evbit);
@@ -1244,6 +1246,7 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
12441246
exit:
12451247
hid_device_io_stop(hdev);
12461248
hid_hw_close(hdev);
1249+
return ret;
12471250
}
12481251

12491252
static int rmi_input_mapping(struct hid_device *hdev,

drivers/hid/hid-sony.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,20 +1360,27 @@ static int sony_register_touchpad(struct hid_input *hi, int touch_count,
13601360
return 0;
13611361
}
13621362

1363-
static void sony_input_configured(struct hid_device *hdev,
1363+
static int sony_input_configured(struct hid_device *hdev,
13641364
struct hid_input *hidinput)
13651365
{
13661366
struct sony_sc *sc = hid_get_drvdata(hdev);
1367+
int ret;
13671368

13681369
/*
13691370
* The Dualshock 4 touchpad supports 2 touches and has a
13701371
* resolution of 1920x942 (44.86 dots/mm).
13711372
*/
13721373
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) {
13741376
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+
}
13761381
}
1382+
1383+
return 0;
13771384
}
13781385

13791386
/*

drivers/hid/hid-uclogic.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ static int uclogic_input_mapping(struct hid_device *hdev, struct hid_input *hi,
731731
return 0;
732732
}
733733

734-
static void uclogic_input_configured(struct hid_device *hdev,
734+
static int uclogic_input_configured(struct hid_device *hdev,
735735
struct hid_input *hi)
736736
{
737737
char *name;
@@ -741,7 +741,7 @@ static void uclogic_input_configured(struct hid_device *hdev,
741741

742742
/* no report associated (HID_QUIRK_MULTI_INPUT not set) */
743743
if (!hi->report)
744-
return;
744+
return 0;
745745

746746
field = hi->report->field[0];
747747

@@ -774,6 +774,8 @@ static void uclogic_input_configured(struct hid_device *hdev,
774774
hi->input->name = name;
775775
}
776776
}
777+
778+
return 0;
777779
}
778780

779781
/**

include/linux/hid.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,8 @@ struct hid_driver {
698698
int (*input_mapped)(struct hid_device *hdev,
699699
struct hid_input *hidinput, struct hid_field *field,
700700
struct hid_usage *usage, unsigned long **bit, int *max);
701-
void (*input_configured)(struct hid_device *hdev,
702-
struct hid_input *hidinput);
701+
int (*input_configured)(struct hid_device *hdev,
702+
struct hid_input *hidinput);
703703
void (*feature_mapping)(struct hid_device *hdev,
704704
struct hid_field *field,
705705
struct hid_usage *usage);

0 commit comments

Comments
 (0)