am7xxx: return EINVAL instead of ENOTSUP in am7xxx_get_device_info() All the other error paths about invalid results or unsupported operations return EINVAL, so remove the only instance of ENOTSUP. Since the API documentation makes no promises on the actual negative value of the returned error, this little change of behavior should be fine.
am7xxx: fix C99 conformance for printf & co. when compiling with MinGW C99 format specifiers like "%hhd" are used with log_message() but MinGW (and Windows) does not really supports them, so the compiler suggests to use the "gnu_printf" attribute for the function. However "gnu_printf"is not available on clang so it's not an option, a better alternative is the solution suggested by MinGW at https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ The change fixes the following warnings when compiling with MinGW: .../libam7xxx/src/am7xxx.c: In function ‘log_message’: .../libam7xxx/src/am7xxx.c:647:3: warning: function ‘log_message’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format] vfprintf(stderr, fmt, ap); ^~~~~~~~ .../libam7xxx/src/am7xxx.c: In function ‘open_device’: .../libam7xxx/src/am7xxx.c:772:15: warning: unknown conversion type character ‘h’ in format [-Wformat=] debug(ctx, "Cannot set configuration %hhu\n", ^ .../libam7xxx/src/am7xxx.c:65:85: note: in definition of macro ‘debug’ #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) ^~~~~~~~~~~ .../libam7xxx/src/am7xxx.c:772:15: warning: too many arguments for format [-Wformat-extra-args] debug(ctx, "Cannot set configuration %hhu\n", ^ .../libam7xxx/src/am7xxx.c:65:85: note: in definition of macro ‘debug’ #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) ^~~~~~~~~~~ .../libam7xxx/src/am7xxx.c:785:14: warning: unknown conversion type character ‘h’ in format [-Wformat=] debug(ctx, "Cannot claim interface %hhu\n", ^ .../libam7xxx/src/am7xxx.c:65:85: note: in definition of macro ‘debug’ #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) ^~~~~~~~~~~ .../libam7xxx/src/am7xxx.c:785:14: warning: too many arguments for format [-Wformat-extra-args] debug(ctx, "Cannot claim interface %hhu\n", ^ .../libam7xxx/src/am7xxx.c:65:85: note: in definition of macro ‘debug’ #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) ^~~~~~~~~~~ .../libam7xxx/src/am7xxx.c:803:14: warning: unknown conversion type character ‘h’ in format [-Wformat=] debug(ctx, "libusb configuration changed (expected: %hhu, current: %d)\n", ^ .../libam7xxx/src/am7xxx.c:65:85: note: in definition of macro ‘debug’ #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) ^~~~~~~~~~~ .../libam7xxx/src/am7xxx.c:803:14: warning: too many arguments for format [-Wformat-extra-args] debug(ctx, "libusb configuration changed (expected: %hhu, current: %d)\n", ^ .../libam7xxx/src/am7xxx.c:65:85: note: in definition of macro ‘debug’ #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) ^~~~~~~~~~~
am7xxx: use the same indenting style for all preprocessor directives While at it also reformat a multi-line comment to follow the style of the other comments.
am7xxx: specify LIBUSB_CALL for send_data_async_complete_cb() send_data_async_complete_cb() is used as a callback for libusb_fill_bulk_transfer() and it is expected to be of type 'libusb_transfer_cb_fn' which is defined using LIBUSB_CALL. LIBUSB_CALL is only used on Windows and not having it results in the following warning when compiling for Windows: .../libam7xxx/src/am7xxx.c: In function ‘send_data_async’: .../libam7xxx/src/am7xxx.c:508:7: warning: passing argument 6 of ‘libusb_fill_bulk_transfer’ from incompatible pointer type [-Wincompatible-pointer-types] send_data_async_complete_cb, dev, 0); ^~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /home/ao2/Proj/picoProjector/libam7xxx/src/am7xxx.c:24:0: .../libam7xxx/build/libusb-1.0.21/include/libusb-1.0/libusb.h:1553:20: note: expected ‘libusb_transfer_cb_fn’ but argument is of type ‘void (*)(struct libusb_transfer *)’ static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, ^~~~~~~~~~~~~~~~~~~~~~~~~
am7xxx: simplify the device info caching operation in am7xxx_open_device() Now that am7xxx_get_device_info() is more robust, the check in the caller can be avoided.
am7xxx: make sure am7xxx_get_device_info() always returns sensible values am7xxx_get_device_info() was not covering the case of a non-NULL output parameter on the very first invocation, this case would not usually happen in normal operation, but the problem was there: in that case the output device_info structure would have contained garbage, as spotted by the static analyzer: .../src/am7xxx.c:1279:21: warning: The right operand of '<=' is a garbage value original_width <= device_info.native_width && ^ ~~~~~~~~~~~~~~~~~~~~~~~~ .../src/am7xxx.c:1288:39: warning: The right operand of '/' is a garbage value width_ratio = (float)original_width / device_info.native_width; ^ ~~~~~~~~~~~~~~~~~~~~~~~~ While at it also fix the symmetric case of a NULL output parameter on subsequent invocation: check that the output argument is non-NULL before memcpy-ing to it.
am7xxx: simplify one return path in am7xxx_init() Just return directly when there is no cleanup to do, it is more readable.
Fix a missing parenthesis in some output strings
am7xxx: remove a useless empty line
Fix some format string warnings from clang Building with clang gives some format string warnings as below, fix them by using the correct format string when printing out the values. .../libam7xxx/src/am7xxx.c:804:38: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat] (*dev)->desc->configuration, current_configuration); ^~~~~~~~~~~~~~~~~~~~~ .../libam7xxx/src/am7xxx.c:65:85: note: expanded from macro 'debug' #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) ^ 1 warning generated. [...] .../libam7xxx/examples/am7xxx-modeswitch.c:75:5: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat] AM7XXX_STORAGE_CONFIGURATION); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ .../libam7xxx/examples/am7xxx-modeswitch.c:26:38: note: expanded from macro 'AM7XXX_STORAGE_CONFIGURATION' #define AM7XXX_STORAGE_CONFIGURATION 1 ^ .../libam7xxx/examples/am7xxx-modeswitch.c:87:4: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat] AM7XXX_STORAGE_INTERFACE); ^~~~~~~~~~~~~~~~~~~~~~~~ .../libam7xxx/examples/am7xxx-modeswitch.c:27:38: note: expanded from macro 'AM7XXX_STORAGE_INTERFACE' #define AM7XXX_STORAGE_INTERFACE 0 ^ .../libam7xxx/examples/am7xxx-modeswitch.c:104:4: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat] AM7XXX_STORAGE_CONFIGURATION, current_configuration); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ .../libam7xxx/examples/am7xxx-modeswitch.c:26:38: note: expanded from macro 'AM7XXX_STORAGE_CONFIGURATION' #define AM7XXX_STORAGE_CONFIGURATION 1 ^ .../libam7xxx/examples/am7xxx-modeswitch.c:104:34: warning: format specifies type 'unsigned char' but the argument has type 'int' [-Wformat] AM7XXX_STORAGE_CONFIGURATION, current_configuration); ^~~~~~~~~~~~~~~~~~~~~ 4 warnings generated.
am7xxx: put some spaces around operators
am7xxx: remove a redundant debug message in open_device() The calling function will show an error for the same condition.
am7xxx: use debug() instead of fatal() in add_new_device() We are guaranteed that ctx is non-null by a previous check.
am7xxx: rename the "function" argument of log_message() to "function_name" This express better the meaning of the variable.
am7xxx: split declaration and initialization of the "transferred" variable This makes it clearer than we mean to initialize the variable to 0 before _each_ libusb_bulk_transfer() call.
am7xxx: print an error message when libusb_init fails
am7xxx: improve the comment about setting a new configuration Explain better why it is not needed to detach all kernel drivers in most situations.
am7xxx: clarify a comment about copying data in send_data_async()
am7xxx: release the interface when needed in open_device() Release the interface when bailing out of open_device() after the interface has been claimed.
am7xxx: check the return value of libusb_get_configuration() libusb_get_configuration() can still fail after the device has been opened, so check its actual return value before trusting the returned current_configuration.