@@ -2783,6 +2783,9 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
27832783{
27842784 struct hidpp_device * hidpp = hid_get_drvdata (hdev );
27852785
2786+ if (!hidpp )
2787+ return 0 ;
2788+
27862789 if (hidpp -> quirks & HIDPP_QUIRK_CLASS_WTP )
27872790 return wtp_input_mapping (hdev , hi , field , usage , bit , max );
27882791 else if (hidpp -> quirks & HIDPP_QUIRK_CLASS_M560 &&
@@ -2798,6 +2801,9 @@ static int hidpp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
27982801{
27992802 struct hidpp_device * hidpp = hid_get_drvdata (hdev );
28002803
2804+ if (!hidpp )
2805+ return 0 ;
2806+
28012807 /* Ensure that Logitech G920 is not given a default fuzz/flat value */
28022808 if (hidpp -> quirks & HIDPP_QUIRK_CLASS_G920 ) {
28032809 if (usage -> type == EV_ABS && (usage -> code == ABS_X ||
@@ -2829,6 +2835,9 @@ static int hidpp_input_configured(struct hid_device *hdev,
28292835 struct hidpp_device * hidpp = hid_get_drvdata (hdev );
28302836 struct input_dev * input = hidinput -> input ;
28312837
2838+ if (!hidpp )
2839+ return 0 ;
2840+
28322841 hidpp_populate_input (hidpp , input , true);
28332842
28342843 return 0 ;
@@ -2898,6 +2907,9 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
28982907 struct hidpp_device * hidpp = hid_get_drvdata (hdev );
28992908 int ret = 0 ;
29002909
2910+ if (!hidpp )
2911+ return 0 ;
2912+
29012913 /* Generic HID++ processing. */
29022914 switch (data [0 ]) {
29032915 case REPORT_ID_HIDPP_VERY_LONG :
@@ -2946,7 +2958,12 @@ static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
29462958 * restriction imposed in hidpp_usages.
29472959 */
29482960 struct hidpp_device * hidpp = hid_get_drvdata (hdev );
2949- struct hidpp_scroll_counter * counter = & hidpp -> vertical_wheel_counter ;
2961+ struct hidpp_scroll_counter * counter ;
2962+
2963+ if (!hidpp )
2964+ return 0 ;
2965+
2966+ counter = & hidpp -> vertical_wheel_counter ;
29502967 /* A scroll event may occur before the multiplier has been retrieved or
29512968 * the input device set, or high-res scroll enabling may fail. In such
29522969 * cases we must return early (falling back to default behaviour) to
@@ -3202,13 +3219,60 @@ static const struct attribute_group ps_attribute_group = {
32023219 .attrs = sysfs_attrs
32033220};
32043221
3222+ static bool hidpp_validate_report (struct hid_device * hdev , int id , int size ,
3223+ bool optional )
3224+ {
3225+ struct hid_report_enum * re ;
3226+ struct hid_report * report ;
3227+
3228+ if (id >= HID_MAX_IDS || id < 0 ) {
3229+ hid_err (hdev , "invalid HID report id %u\n" , id );
3230+ return false;
3231+ }
3232+
3233+ re = & (hdev -> report_enum [HID_OUTPUT_REPORT ]);
3234+ report = re -> report_id_hash [id ];
3235+
3236+ if (!report )
3237+ return optional ;
3238+
3239+ if (report -> field [0 ]-> report_count < size ) {
3240+ hid_warn (hdev , "not enough values in hidpp report %d\n" , id );
3241+ return false;
3242+ }
3243+
3244+ return true;
3245+ }
3246+
3247+ static bool hidpp_validate_device (struct hid_device * hdev )
3248+ {
3249+ return hidpp_validate_report (hdev , REPORT_ID_HIDPP_SHORT ,
3250+ HIDPP_REPORT_SHORT_LENGTH - 1 , false) &&
3251+ hidpp_validate_report (hdev , REPORT_ID_HIDPP_LONG ,
3252+ HIDPP_REPORT_LONG_LENGTH - 1 , true) &&
3253+ hidpp_validate_report (hdev , REPORT_ID_HIDPP_VERY_LONG ,
3254+ HIDPP_REPORT_VERY_LONG_LENGTH - 1 , true);
3255+ }
3256+
32053257static int hidpp_probe (struct hid_device * hdev , const struct hid_device_id * id )
32063258{
32073259 struct hidpp_device * hidpp ;
32083260 int ret ;
32093261 bool connected ;
32103262 unsigned int connect_mask = HID_CONNECT_DEFAULT ;
32113263
3264+ ret = hid_parse (hdev );
3265+ if (ret ) {
3266+ hid_err (hdev , "%s:parse failed\n" , __func__ );
3267+ return ret ;
3268+ }
3269+
3270+ /*
3271+ * Make sure the device is HID++ capable, otherwise treat as generic HID
3272+ */
3273+ if (!hidpp_validate_device (hdev ))
3274+ return hid_hw_start (hdev , HID_CONNECT_DEFAULT );
3275+
32123276 hidpp = devm_kzalloc (& hdev -> dev , sizeof (struct hidpp_device ),
32133277 GFP_KERNEL );
32143278 if (!hidpp )
@@ -3252,12 +3316,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
32523316 hid_warn (hdev , "Cannot allocate sysfs group for %s\n" ,
32533317 hdev -> name );
32543318
3255- ret = hid_parse (hdev );
3256- if (ret ) {
3257- hid_err (hdev , "%s:parse failed\n" , __func__ );
3258- goto hid_parse_fail ;
3259- }
3260-
32613319 if (hidpp -> quirks & HIDPP_QUIRK_NO_HIDINPUT )
32623320 connect_mask &= ~HID_CONNECT_HIDINPUT ;
32633321
@@ -3330,7 +3388,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
33303388 hid_hw_stop (hdev );
33313389 }
33323390hid_hw_start_fail :
3333- hid_parse_fail :
33343391 sysfs_remove_group (& hdev -> dev .kobj , & ps_attribute_group );
33353392 cancel_work_sync (& hidpp -> work );
33363393 mutex_destroy (& hidpp -> send_mutex );
@@ -3341,6 +3398,9 @@ static void hidpp_remove(struct hid_device *hdev)
33413398{
33423399 struct hidpp_device * hidpp = hid_get_drvdata (hdev );
33433400
3401+ if (!hidpp )
3402+ return hid_hw_stop (hdev );
3403+
33443404 sysfs_remove_group (& hdev -> dev .kobj , & ps_attribute_group );
33453405
33463406 if (hidpp -> quirks & HIDPP_QUIRK_CLASS_G920 ) {
0 commit comments