@@ -55,6 +55,9 @@ typedef struct {
5555 char * serial_number ;
5656 char * guid ;
5757
58+ unsigned int usb_major_version ;
59+ unsigned int usb_minor_version ;
60+
5861 libusb_context * usb ;
5962 libusb_device_handle * usb_device ;
6063
@@ -72,8 +75,9 @@ typedef struct {
7275 guint ack_packet_size_max ;
7376 guint control_interface ;
7477 guint data_interface ;
75- guint8 control_endpoint ;
76- guint8 data_endpoint ;
78+ guint8 control_endpoint_out ;
79+ guint8 control_endpoint_in ;
80+ guint8 data_endpoint ;
7781 gboolean disconnected ;
7882
7983 ArvUvUsbMode usb_mode ;
@@ -141,9 +145,13 @@ arv_uv_device_fill_bulk_transfer (struct libusb_transfer* transfer, ArvUvDevice
141145 ArvUvDevicePrivate * priv = arv_uv_device_get_instance_private (uv_device );
142146 guint8 endpoint ;
143147
144- endpoint = (endpoint_type == ARV_UV_ENDPOINT_CONTROL ) ? priv -> control_endpoint : priv -> data_endpoint ;
148+ if (endpoint_type == ARV_UV_ENDPOINT_CONTROL ) {
149+ endpoint = (endpoint_flags == LIBUSB_ENDPOINT_IN ) ? priv -> control_endpoint_in : priv -> control_endpoint_out ;
150+ } else {
151+ endpoint = priv -> data_endpoint ;
152+ }
145153
146- libusb_fill_bulk_transfer (transfer , priv -> usb_device , endpoint | endpoint_flags , data , size ,
154+ libusb_fill_bulk_transfer (transfer , priv -> usb_device , endpoint , data , size ,
147155 callback , callback_data , timeout );
148156}
149157
@@ -167,9 +175,12 @@ arv_uv_device_bulk_transfer (ArvUvDevice *uv_device, ArvUvEndpointType endpoint_
167175 return FALSE;
168176 }
169177
170-
171- endpoint = (endpoint_type == ARV_UV_ENDPOINT_CONTROL ) ? priv -> control_endpoint : priv -> data_endpoint ;
172- result = libusb_bulk_transfer (priv -> usb_device , endpoint | endpoint_flags , data , size , & transferred ,
178+ if (endpoint_type == ARV_UV_ENDPOINT_CONTROL ) {
179+ endpoint = (endpoint_flags == LIBUSB_ENDPOINT_IN ) ? priv -> control_endpoint_in : priv -> control_endpoint_out ;
180+ } else {
181+ endpoint = priv -> data_endpoint ;
182+ }
183+ result = libusb_bulk_transfer (priv -> usb_device , endpoint , data , size , & transferred ,
173184 timeout_ms > 0 ? timeout_ms : priv -> timeout_ms );
174185
175186 success = result >= 0 ;
@@ -708,7 +719,7 @@ arv_uv_device_get_genicam_xml (ArvDevice *device, size_t *size)
708719}
709720
710721static void
711- reset_endpoint (libusb_device_handle * usb_device , guint8 endpoint , guint8 endpoint_flags )
722+ reset_endpoint (libusb_device_handle * usb_device , guint8 endpoint )
712723{
713724 int errcode ;
714725
@@ -717,17 +728,17 @@ reset_endpoint (libusb_device_handle *usb_device, guint8 endpoint, guint8 endpoi
717728 LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_ENDPOINT ,
718729 LIBUSB_REQUEST_SET_FEATURE ,
719730 0 , /* Value: 0=endpoint_halt */
720- endpoint | endpoint_flags ,
731+ endpoint ,
721732 0 , 0 ,
722733 1000 );
723734 if (errcode < 0 ) {
724735 arv_warning_device ("Failed to set endpoint %x in halt condition: %s" ,
725- endpoint | endpoint_flags , libusb_error_name (errcode ));
736+ endpoint , libusb_error_name (errcode ));
726737 return ;
727738 }
728739
729740 /* Clear halt condtion on the endpoint, effectivelly resetting the pipe */
730- errcode = libusb_clear_halt (usb_device , endpoint | endpoint_flags );
741+ errcode = libusb_clear_halt (usb_device , endpoint );
731742 if (errcode < 0 ) {
732743 arv_warning_device ("Failed to clear halt contidion on endpoint: %s" ,
733744 libusb_error_name (errcode ));
@@ -742,7 +753,7 @@ arv_uv_device_reset_stream_endpoint (ArvUvDevice *device)
742753
743754 g_return_val_if_fail (ARV_IS_UV_DEVICE (device ), FALSE);
744755
745- reset_endpoint (priv -> usb_device , priv -> data_endpoint , LIBUSB_ENDPOINT_IN );
756+ reset_endpoint (priv -> usb_device , priv -> data_endpoint );
746757
747758 return TRUE;
748759}
@@ -845,6 +856,9 @@ _open_usb_device (ArvUvDevice *uv_device, GError **error)
845856 if (priv -> guid == NULL )
846857 priv -> guid = g_strdup ((char * ) guid );
847858
859+ priv -> usb_major_version = ((desc .bcdUSB >> 12 ) & 0xf ) * 10 + ((desc .bcdUSB >> 8 ) & 0xf );
860+ priv -> usb_minor_version = ((desc .bcdUSB >> 4 ) & 0xf ) * 10 + (desc .bcdUSB & 0xf );
861+
848862 result = libusb_set_auto_detach_kernel_driver (usb_device , 1 );
849863 if (result != 0 ) {
850864 arv_warning_device ("Failed to set auto kernel detach feature "
@@ -861,13 +875,19 @@ _open_usb_device (ArvUvDevice *uv_device, GError **error)
861875 if (interdesc -> bInterfaceClass == ARV_UV_INTERFACE_INTERFACE_CLASS &&
862876 interdesc -> bInterfaceSubClass == ARV_UV_INTERFACE_INTERFACE_SUBCLASS ) {
863877 if (interdesc -> bInterfaceProtocol == ARV_UV_INTERFACE_CONTROL_PROTOCOL ) {
864- endpoint = interdesc -> endpoint [0 ];
865- priv -> control_endpoint = endpoint .bEndpointAddress & 0x0f ;
878+ for (int edx = 0 ; edx < interdesc -> bNumEndpoints ; edx ++ ) {
879+ endpoint = interdesc -> endpoint [edx ];
880+ if ((endpoint .bEndpointAddress & LIBUSB_ENDPOINT_IN ) != 0 ) {
881+ priv -> control_endpoint_in = endpoint .bEndpointAddress ;
882+ } else {
883+ priv -> control_endpoint_out = endpoint .bEndpointAddress ;
884+ }
885+ }
866886 priv -> control_interface = interdesc -> bInterfaceNumber ;
867887 }
868888 if (interdesc -> bInterfaceProtocol == ARV_UV_INTERFACE_DATA_PROTOCOL ) {
869889 endpoint = interdesc -> endpoint [0 ];
870- priv -> data_endpoint = endpoint .bEndpointAddress & 0x0f ;
890+ priv -> data_endpoint = endpoint .bEndpointAddress ;
871891 priv -> data_interface = interdesc -> bInterfaceNumber ;
872892 }
873893 }
@@ -1032,9 +1052,16 @@ arv_uv_device_constructed (GObject *object)
10321052 return ;
10331053 }
10341054
1035- arv_info_device ("[UvDevice::new] Using control endpoint %d, interface %d" ,
1036- priv -> control_endpoint , priv -> control_interface );
1037- arv_info_device ("[UvDevice::new] Using data endpoint %d, interface %d" ,
1055+ if (priv -> usb_major_version < 3 )
1056+ arv_warning_device ("[UvDevice::new] USB %d.%d (Low bandwidth)" ,
1057+ priv -> usb_major_version , priv -> usb_minor_version );
1058+ else
1059+ arv_info_device ("[UvDevice::new] USB %d.%d" ,
1060+ priv -> usb_major_version , priv -> usb_minor_version );
1061+
1062+ arv_info_device ("[UvDevice::new] Using control endpoint OUT=0x%02x IN=0x%02x, interface %d" ,
1063+ priv -> control_endpoint_out , priv -> control_endpoint_in , priv -> control_interface );
1064+ arv_info_device ("[UvDevice::new] Using data endpoint 0x%02x, interface %d" ,
10381065 priv -> data_endpoint , priv -> data_interface );
10391066
10401067 result = libusb_claim_interface (priv -> usb_device , priv -> control_interface );
0 commit comments