lowlevel.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. struct lowlevel_device_info *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. return devinfo_list;
  85. }
  86. #define DETECT_BEGIN \
  87. struct lowlevel_device_info *info, *tmp; \
  88. int found = 0; \
  89. \
  90. LL_FOREACH_SAFE(devinfo_list, info, tmp) \
  91. { \
  92. // END DETECT_BEGIN
  93. #define DETECT_PREEND \
  94. if (!cb(info, userp)) \
  95. continue; \
  96. LL_DELETE(devinfo_list, info); \
  97. ++found; \
  98. // END DETECT_PREEND
  99. #define DETECT_END \
  100. } \
  101. return found; \
  102. // END DETECT_END
  103. int _lowlevel_detect(lowl_found_devinfo_func_t cb, const char *serial, const char **product_needles, void * const userp)
  104. {
  105. int i;
  106. DETECT_BEGIN
  107. if (serial && ((!info->serial) || strcmp(serial, info->serial)))
  108. continue;
  109. if (product_needles[0] && !info->product)
  110. continue;
  111. for (i = 0; product_needles[i]; ++i)
  112. if (!strstr(info->product, product_needles[i]))
  113. goto next;
  114. DETECT_PREEND
  115. next: ;
  116. DETECT_END
  117. }
  118. 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)
  119. {
  120. DETECT_BEGIN
  121. if (info->lowl != lowl)
  122. continue;
  123. if (vid != -1 && vid != info->vid)
  124. continue;
  125. if (pid != -1 && pid != info->pid)
  126. continue;
  127. DETECT_PREEND
  128. DETECT_END
  129. }