lowlevel.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 USE_NANOFURY
  63. devinfo_mid_list = lowl_mcp2210.devinfo_scan();
  64. LL_CONCAT(devinfo_list, devinfo_mid_list);
  65. #endif
  66. #ifdef HAVE_FPGAUTILS
  67. devinfo_mid_list = lowl_vcom.devinfo_scan();
  68. LL_CONCAT(devinfo_list, devinfo_mid_list);
  69. #endif
  70. LL_FOREACH(devinfo_list, devinfo_mid_list)
  71. {
  72. applog(LOG_DEBUG, "%s: Found %s device at %s (path=%s, vid=%04x, pid=%04x, manuf=%s, prod=%s, serial=%s)",
  73. __func__,
  74. devinfo_mid_list->lowl->dname,
  75. devinfo_mid_list->devid,
  76. devinfo_mid_list->path,
  77. (unsigned)devinfo_mid_list->vid, (unsigned)devinfo_mid_list->pid,
  78. devinfo_mid_list->manufacturer, devinfo_mid_list->product, devinfo_mid_list->serial);
  79. }
  80. }
  81. #define DETECT_BEGIN \
  82. struct lowlevel_device_info *info, *tmp; \
  83. int found = 0; \
  84. \
  85. LL_FOREACH_SAFE(devinfo_list, info, tmp) \
  86. { \
  87. // END DETECT_BEGIN
  88. #define DETECT_PREEND \
  89. if (!cb(info, userp)) \
  90. continue; \
  91. LL_DELETE(devinfo_list, info); \
  92. ++found; \
  93. // END DETECT_PREEND
  94. #define DETECT_END \
  95. } \
  96. return found; \
  97. // END DETECT_END
  98. int _lowlevel_detect(lowl_found_devinfo_func_t cb, const char *serial, const char **product_needles, void * const userp)
  99. {
  100. int i;
  101. DETECT_BEGIN
  102. if (serial && ((!info->serial) || strcmp(serial, info->serial)))
  103. continue;
  104. if (product_needles[0] && !info->product)
  105. continue;
  106. for (i = 0; product_needles[i]; ++i)
  107. if (!strstr(info->product, product_needles[i]))
  108. goto next;
  109. DETECT_PREEND
  110. next: ;
  111. DETECT_END
  112. }
  113. 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)
  114. {
  115. DETECT_BEGIN
  116. if (info->lowl != lowl)
  117. continue;
  118. if (vid != -1 && vid != info->vid)
  119. continue;
  120. if (pid != -1 && pid != info->pid)
  121. continue;
  122. DETECT_PREEND
  123. DETECT_END
  124. }