lowlevel.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright 2012-2013 Luke Dashjr
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include <stdint.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <utlist.h>
  14. #include "logging.h"
  15. #include "lowlevel.h"
  16. static struct lowlevel_device_info *devinfo_list;
  17. void lowlevel_devinfo_semicpy(struct lowlevel_device_info * const dst, const struct lowlevel_device_info * const src)
  18. {
  19. #define COPYSTR(key) BFGINIT(dst->key, maybe_strdup(src->key))
  20. COPYSTR(manufacturer);
  21. COPYSTR(product);
  22. COPYSTR(serial);
  23. COPYSTR(path);
  24. COPYSTR(devid);
  25. BFGINIT(dst->vid, src->vid);
  26. BFGINIT(dst->pid, src->pid);
  27. }
  28. void lowlevel_devinfo_free(struct lowlevel_device_info * const info)
  29. {
  30. if (info->lowl->devinfo_free)
  31. info->lowl->devinfo_free(info);
  32. free(info->manufacturer);
  33. free(info->product);
  34. free(info->serial);
  35. free(info->path);
  36. free(info->devid);
  37. free(info);
  38. }
  39. void lowlevel_scan_free()
  40. {
  41. if (!devinfo_list)
  42. return;
  43. struct lowlevel_device_info *info, *tmp;
  44. LL_FOREACH_SAFE(devinfo_list, info, tmp)
  45. {
  46. LL_DELETE(devinfo_list, info);
  47. lowlevel_devinfo_free(info);
  48. }
  49. }
  50. void lowlevel_scan()
  51. {
  52. struct lowlevel_device_info *devinfo_mid_list;
  53. lowlevel_scan_free();
  54. #ifdef HAVE_LIBUSB
  55. devinfo_mid_list = lowl_usb.devinfo_scan();
  56. LL_CONCAT(devinfo_list, devinfo_mid_list);
  57. #endif
  58. #ifdef USE_X6500
  59. devinfo_mid_list = lowl_ft232r.devinfo_scan();
  60. LL_CONCAT(devinfo_list, devinfo_mid_list);
  61. #endif
  62. #ifdef NEED_BFG_LOWL_HID
  63. devinfo_mid_list = lowl_hid.devinfo_scan();
  64. LL_CONCAT(devinfo_list, devinfo_mid_list);
  65. #endif
  66. #ifdef USE_NANOFURY
  67. devinfo_mid_list = lowl_mcp2210.devinfo_scan();
  68. LL_CONCAT(devinfo_list, devinfo_mid_list);
  69. #endif
  70. #ifdef HAVE_FPGAUTILS
  71. devinfo_mid_list = lowl_vcom.devinfo_scan();
  72. LL_CONCAT(devinfo_list, devinfo_mid_list);
  73. #endif
  74. LL_FOREACH(devinfo_list, devinfo_mid_list)
  75. {
  76. applog(LOG_DEBUG, "%s: Found %s device at %s (path=%s, vid=%04x, pid=%04x, manuf=%s, prod=%s, serial=%s)",
  77. __func__,
  78. devinfo_mid_list->lowl->dname,
  79. devinfo_mid_list->devid,
  80. devinfo_mid_list->path,
  81. (unsigned)devinfo_mid_list->vid, (unsigned)devinfo_mid_list->pid,
  82. devinfo_mid_list->manufacturer, devinfo_mid_list->product, devinfo_mid_list->serial);
  83. }
  84. }
  85. #define DETECT_BEGIN \
  86. struct lowlevel_device_info *info, *tmp; \
  87. int found = 0; \
  88. \
  89. LL_FOREACH_SAFE(devinfo_list, info, tmp) \
  90. { \
  91. // END DETECT_BEGIN
  92. #define DETECT_PREEND \
  93. if (!cb(info, userp)) \
  94. continue; \
  95. LL_DELETE(devinfo_list, info); \
  96. ++found; \
  97. // END DETECT_PREEND
  98. #define DETECT_END \
  99. } \
  100. return found; \
  101. // END DETECT_END
  102. int _lowlevel_detect(lowl_found_devinfo_func_t cb, const char *serial, const char **product_needles, void * const userp)
  103. {
  104. int i;
  105. DETECT_BEGIN
  106. if (serial && ((!info->serial) || strcmp(serial, info->serial)))
  107. continue;
  108. if (product_needles[0] && !info->product)
  109. continue;
  110. for (i = 0; product_needles[i]; ++i)
  111. if (!strstr(info->product, product_needles[i]))
  112. goto next;
  113. DETECT_PREEND
  114. next: ;
  115. DETECT_END
  116. }
  117. int lowlevel_detect_id(const lowl_found_devinfo_func_t cb, void * const userp, const struct lowlevel_driver * const lowl, const int32_t vid, const int32_t pid)
  118. {
  119. DETECT_BEGIN
  120. if (info->lowl != lowl)
  121. continue;
  122. if (vid != -1 && vid != info->vid)
  123. continue;
  124. if (pid != -1 && pid != info->pid)
  125. continue;
  126. DETECT_PREEND
  127. DETECT_END
  128. }