@@ -637,7 +637,7 @@ static int parse_uevent_info(const char *uevent, unsigned *bus_type,
637637}
638638
639639
640- static struct hid_device_info * create_device_info_for_device (struct udev_device * raw_dev )
640+ static struct hid_device_info * create_device_info_for_device (struct udev_device * raw_dev , long report_timeout_msec )
641641{
642642 struct hid_device_info * root = NULL ;
643643 struct hid_device_info * cur_dev = NULL ;
@@ -792,8 +792,29 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device
792792
793793 /* Usage Page and Usage */
794794
795- if (sysfs_path ) {
796- result = get_hid_report_descriptor_from_sysfs (sysfs_path , & report_desc );
795+ if (sysfs_path ) {
796+ struct timeval tv_start ;
797+ struct timezone tz ;
798+ long time_diff_usec = -1 ;
799+ result = -1 ;
800+
801+ gettimeofday (& tv_start , & tz );
802+ long report_timeout_usec = report_timeout_msec * 1000L ;
803+
804+ while (time_diff_usec < report_timeout_usec && result < 0 )
805+ {
806+ result = get_hid_report_descriptor_from_sysfs (sysfs_path , & report_desc );
807+
808+ struct timeval tv_end ;
809+ gettimeofday (& tv_end , & tz );
810+ time_diff_usec = (tv_end .tv_sec - tv_start .tv_sec ) * 1000000L + (tv_end .tv_usec - tv_start .tv_usec );
811+
812+ if ((result < 0 ) && (report_timeout_usec > 0L ))
813+ {
814+ // Make a short sleep before retrying (1 millisecond is ok)
815+ usleep (1000 );
816+ }
817+ }
797818 }
798819 else {
799820 result = -1 ;
@@ -876,7 +897,7 @@ static struct hid_device_info * create_device_info_for_hid_device(hid_device *de
876897 /* Open a udev device from the dev_t. 'c' means character device. */
877898 udev_dev = udev_device_new_from_devnum (udev , 'c' , s .st_rdev );
878899 if (udev_dev ) {
879- root = create_device_info_for_device (udev_dev );
900+ root = create_device_info_for_device (udev_dev , 0 );
880901 }
881902
882903 if (!root ) {
@@ -1113,7 +1134,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
11131134 if (!raw_dev )
11141135 continue ;
11151136
1116- tmp = create_device_info_for_device (raw_dev );
1137+ tmp = create_device_info_for_device (raw_dev , 0 );
11171138 if (tmp ) {
11181139 if (cur_dev ) {
11191140 cur_dev -> next = tmp ;
@@ -1237,7 +1258,9 @@ static void* hotplug_thread(void* user_data)
12371258 const char * action = udev_device_get_action (raw_dev );
12381259 if (!strcmp (action , "add" )) {
12391260 // We create a list of all usages on this UDEV device
1240- struct hid_device_info * info = create_device_info_for_device (raw_dev );
1261+ // NOTE: The device may not be ready to work immediately when the event is received
1262+ // We let the device up to 4 seconds to become ready to provide the descriptor
1263+ struct hid_device_info * info = create_device_info_for_device (raw_dev , 4000L );
12411264 struct hid_device_info * info_cur = info ;
12421265 while (info_cur ) {
12431266 /* For each device, call all matching callbacks */
0 commit comments