driver-knc-titan.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright 2014 Vitalii Demianets
  3. * Copyright 2014 KnCMiner
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the Free
  7. * Software Foundation; either version 3 of the License, or (at your option)
  8. * any later version. See COPYING for more details.
  9. */
  10. #include <fcntl.h>
  11. #include "deviceapi.h"
  12. #define KNC_TITAN_MAX_ASICS 6
  13. #define KNC_TITAN_DIES_PER_ASIC 4
  14. #define KNC_TITAN_CORES_PER_DIE 48
  15. #define KNC_TITAN_CORES_PER_ASIC (KNC_TITAN_CORES_PER_DIE * KNC_TITAN_DIES_PER_ASIC)
  16. #define KNC_TITAN_DEFAULT_FREQUENCY 600
  17. BFG_REGISTER_DRIVER(knc_titan_drv)
  18. static const struct bfg_set_device_definition knc_titan_set_device_funcs[];
  19. struct knc_titan_info {
  20. int freq;
  21. };
  22. static bool knc_titan_detect_one(const char *devpath)
  23. {
  24. static struct cgpu_info *prev_cgpu = NULL;
  25. struct cgpu_info *cgpu;
  26. int i;
  27. const int fd = open(devpath, O_RDWR);
  28. uint8_t buf[0x20];
  29. if (unlikely(-1 == fd)) {
  30. applog(LOG_DEBUG, "%s: Failed to open %s", __func__, devpath);
  31. return false;
  32. }
  33. close(fd);
  34. cgpu = malloc(sizeof(*cgpu));
  35. *cgpu = (struct cgpu_info) {
  36. .drv = &knc_titan_drv,
  37. .device_path = strdup(devpath),
  38. .set_device_funcs = knc_titan_set_device_funcs,
  39. .deven = DEV_ENABLED,
  40. .procs = KNC_TITAN_CORES_PER_ASIC,
  41. .threads = prev_cgpu ? 0 : 1,
  42. };
  43. const bool rv = add_cgpu_slave(cgpu, prev_cgpu);
  44. prev_cgpu = cgpu;
  45. return rv;
  46. }
  47. static int knc_titan_detect_auto(void)
  48. {
  49. const int first = 3, last = 3 + KNC_TITAN_MAX_ASICS - 1;
  50. char devpath[256];
  51. int found = 0, i;
  52. for (i = first; i <= last; ++i)
  53. {
  54. sprintf(devpath, "/dev/i2c-%d", i);
  55. if (knc_titan_detect_one(devpath))
  56. ++found;
  57. }
  58. return found;
  59. }
  60. static void knc_titan_detect(void)
  61. {
  62. generic_detect(&knc_titan_drv, knc_titan_detect_one, knc_titan_detect_auto, GDF_REQUIRE_DNAME | GDF_DEFAULT_NOAUTO);
  63. }
  64. static struct knc_titan_info *knc_titan_alloc_info(void)
  65. {
  66. struct knc_titan_info *info = calloc(1, sizeof(struct knc_titan_info));
  67. if (unlikely(!info))
  68. quit(1, "Failed to malloc knc_titan_info");
  69. info->freq = KNC_TITAN_DEFAULT_FREQUENCY;
  70. return info;
  71. }
  72. static bool knc_titan_init(struct thr_info * const thr)
  73. {
  74. struct cgpu_info * const cgpu = thr->cgpu, *proc;
  75. struct knc_titan_info *knc;
  76. knc = malloc(sizeof(*knc));
  77. for (proc = cgpu; proc; proc = proc->next_proc)
  78. {
  79. if (proc->device != proc)
  80. {
  81. applog(LOG_WARNING, "%"PRIpreprv": Extra processor?", proc->proc_repr);
  82. proc = proc->next_proc;
  83. continue;
  84. }
  85. knc = knc_titan_alloc_info();
  86. proc->device_data = knc;
  87. }
  88. cgpu_set_defaults(cgpu);
  89. return true;
  90. }
  91. static int64_t knc_titan_scanhash(struct thr_info *thr, struct work *work, int64_t __maybe_unused max_nonce)
  92. {
  93. return 0;
  94. }
  95. /*
  96. * specify settings / options via RPC or command line
  97. */
  98. /* support for --set-device
  99. * must be set before probing the device
  100. */
  101. static void knc_titan_set_clock_freq(struct cgpu_info * const device, int const val)
  102. {
  103. struct knc_titan_info * const info = device->device_data;
  104. info->freq = val;
  105. }
  106. static const char *knc_titan_set_clock(struct cgpu_info * const device, const char * const option, const char * const setting, char * const replybuf, enum bfg_set_device_replytype * const success)
  107. {
  108. knc_titan_set_clock_freq(device, atoi(setting));
  109. return NULL;
  110. }
  111. static const struct bfg_set_device_definition knc_titan_set_device_funcs[] = {
  112. { "clock", knc_titan_set_clock, NULL },
  113. { NULL },
  114. };
  115. /*
  116. * specify settings / options via TUI
  117. */
  118. #ifdef HAVE_CURSES
  119. static void knc_titan_tui_wlogprint_choices(struct cgpu_info * const proc)
  120. {
  121. wlogprint("[C]lock speed ");
  122. }
  123. static const char *knc_titan_tui_handle_choice(struct cgpu_info * const proc, const int input)
  124. {
  125. static char buf[0x100]; /* Static for replies */
  126. switch (input)
  127. {
  128. case 'c': case 'C':
  129. {
  130. sprintf(buf, "Set clock speed");
  131. char * const setting = curses_input(buf);
  132. knc_titan_set_clock_freq(proc->device, atoi(setting));
  133. return "Clock speed changed\n";
  134. }
  135. }
  136. return NULL;
  137. }
  138. static void knc_titan_wlogprint_status(struct cgpu_info * const proc)
  139. {
  140. wlogprint("Clock speed: N/A\n");
  141. }
  142. #endif
  143. struct device_drv knc_titan_drv =
  144. {
  145. /* metadata */
  146. .dname = "knc-titan",
  147. .name = "KNC",
  148. .supported_algos = POW_SCRYPT,
  149. .drv_detect = knc_titan_detect,
  150. .thread_init = knc_titan_init,
  151. /* specify mining type - scanhash */
  152. .minerloop = minerloop_scanhash,
  153. /* scanhash mining hooks */
  154. .scanhash = knc_titan_scanhash,
  155. /* TUI support - e.g. setting clock via UI */
  156. #ifdef HAVE_CURSES
  157. .proc_wlogprint_status = knc_titan_wlogprint_status,
  158. .proc_tui_wlogprint_choices = knc_titan_tui_wlogprint_choices,
  159. .proc_tui_handle_choice = knc_titan_tui_handle_choice,
  160. #endif
  161. };