Request the actual device info from the device only when there is not
a cached version of it already.
This serves two purposes:
  1. Cover the case when some firmwares provide useful device info
     only under some conditions and spit out bogus data instead when
     these conditions are not met.
  2. Speed up am7xxx_get_device_info() as the USB communication is
     performed only once. AFAWN the device info does not change
     throughout the life of an am7xxx_device.
 struct _am7xxx_device {
        libusb_device_handle *usb_device;
        uint8_t buffer[AM7XXX_HEADER_WIRE_SIZE];
 struct _am7xxx_device {
        libusb_device_handle *usb_device;
        uint8_t buffer[AM7XXX_HEADER_WIRE_SIZE];
+       am7xxx_device_info *device_info;
        am7xxx_context *ctx;
        am7xxx_device *next;
 };
        am7xxx_context *ctx;
        am7xxx_device *next;
 };
 
        while (current) {
                am7xxx_device *next = current->next;
                am7xxx_close_device(current);
        while (current) {
                am7xxx_device *next = current->next;
                am7xxx_close_device(current);
+               free(current->device_info);
                free(current);
                current = next;
        }
                free(current);
                current = next;
        }
 
+       if (dev->device_info) {
+               memcpy(device_info, dev->device_info, sizeof(*device_info));
+               return 0;
+       }
+
        ret = send_header(dev, &h);
        if (ret < 0)
                return ret;
        ret = send_header(dev, &h);
        if (ret < 0)
                return ret;
 
-       device_info->native_width = h.header_data.devinfo.native_width;
-       device_info->native_height = h.header_data.devinfo.native_height;
+       dev->device_info = malloc(sizeof(*dev->device_info));
+       if (dev->device_info == NULL) {
+               error(dev->ctx, "cannot allocate a device info (%s)\n",
+                      strerror(errno));
+               return -ENOMEM;
+       }
+       memset(dev->device_info, 0, sizeof(*dev->device_info));
+
+       dev->device_info->native_width = h.header_data.devinfo.native_width;
+       dev->device_info->native_height = h.header_data.devinfo.native_height;
 #if 0
        /* No reason to expose these in the public API until we know what they mean */
 #if 0
        /* No reason to expose these in the public API until we know what they mean */
-       device_info->unknown0 = h.header_data.devinfo.unknown0;
-       device_info->unknown1 = h.header_data.devinfo.unknown1;
+       dev->device_info->unknown0 = h.header_data.devinfo.unknown0;
+       dev->device_info->unknown1 = h.header_data.devinfo.unknown1;