contrib: add TAG+="uaccess" to udev rules
[libam7xxx.git] / src / am7xxx.c
index 2d7b890..8573a59 100644 (file)
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
-/* If we're not using GNU C, elide __attribute__
+/*
+ * If we're not using GNU C, elide __attribute__
  * taken from: http://unixwiz.net/techtips/gnu-c-attributes.html)
  */
 #ifndef __GNUC__
-#  define  __attribute__(x)  /* NOTHING */
+       #define  __attribute__(x)  /* NOTHING */
+#endif
+
+/*
+ * Fix printf format when compiling for Windows with MinGW, see:
+ * https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/
+ */
+#ifdef __MINGW_PRINTF_FORMAT
+       #define AM7XXX_PRINTF_FORMAT __MINGW_PRINTF_FORMAT
+#else
+       #define AM7XXX_PRINTF_FORMAT printf
 #endif
 
 /* Control shared library symbols visibility */
@@ -56,7 +67,7 @@ static void log_message(am7xxx_context *ctx,
                        const char *function_name,
                        int line,
                        const char *fmt,
-                       ...) __attribute__ ((format (printf, 5, 6)));
+                       ...) __attribute__ ((format (AM7XXX_PRINTF_FORMAT, 5, 6)));
 
 #define fatal(...)        log_message(NULL, AM7XXX_LOG_FATAL,   __func__, __LINE__, __VA_ARGS__)
 #define error(ctx, ...)   log_message(ctx,  AM7XXX_LOG_ERROR,   __func__, __LINE__, __VA_ARGS__)
@@ -414,7 +425,7 @@ static int send_data(am7xxx_device *dev, uint8_t *buffer, unsigned int len)
        return 0;
 }
 
-static void send_data_async_complete_cb(struct libusb_transfer *transfer)
+static void LIBUSB_CALL send_data_async_complete_cb(struct libusb_transfer *transfer)
 {
        am7xxx_device *dev = (am7xxx_device *)(transfer->user_data);
        int *completed = &(dev->transfer_completed);
@@ -1179,14 +1190,14 @@ AM7XXX_PUBLIC int am7xxx_open_device(am7xxx_context *ctx, am7xxx_device **dev,
         * is the first one to be sent to the device in order for it to
         * successfully return the correct device information.
         *
-        * So, if there is not a cached version of it (from a previous open),
-        * we ask for device info at open time,
+        * NOTE: am7xxx_get_device_info() will fetch the actual device info
+        * from the device only the very first time it's called for a given
+        * device, otherwise, it'll return a cached version of the device info
+        * (from a previous call to am7xxx_open_device(), for instance).
         */
-       if ((*dev)->device_info == NULL) {
-               ret = am7xxx_get_device_info(*dev, NULL);
-               if (ret < 0)
-                       error(ctx, "cannot get device info\n");
-       }
+       ret = am7xxx_get_device_info(*dev, NULL);
+       if (ret < 0)
+               error(ctx, "cannot get device info\n");
 
 out:
        return ret;
@@ -1213,10 +1224,9 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev,
        int ret;
        struct am7xxx_header h;
 
-       if (dev->device_info) {
-               memcpy(device_info, dev->device_info, sizeof(*device_info));
-               return 0;
-       }
+       /* if there is a cached copy of the device info, just return that */
+       if (dev->device_info)
+               goto return_value;
 
        ret = send_command(dev, AM7XXX_PACKET_TYPE_DEVINFO);
        if (ret < 0)
@@ -1230,8 +1240,8 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev,
        if (h.packet_type != AM7XXX_PACKET_TYPE_DEVINFO) {
                error(dev->ctx, "expected packet type: %d, got %d instead!\n",
                      AM7XXX_PACKET_TYPE_DEVINFO, h.packet_type);
-               errno = ENOTSUP;
-               return -ENOTSUP;
+               errno = EINVAL;
+               return -EINVAL;
        }
 
        dev->device_info = malloc(sizeof(*dev->device_info));
@@ -1250,6 +1260,9 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev,
        dev->device_info->unknown1 = h.header_data.devinfo.unknown1;
 #endif
 
+return_value:
+       if (device_info)
+               memcpy(device_info, dev->device_info, sizeof(*device_info));
        return 0;
 }