driver-gridseed.c 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273
  1. /*
  2. * Copyright 2013 Faster <develop@gridseed.com>
  3. * Copyright 2012-2013 Andrew Smith
  4. * Copyright 2012 Luke Dashjr
  5. * Copyright 2012 Con Kolivas <kernel@kolivas.org>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the Free
  9. * Software Foundation; either version 3 of the License, or (at your option)
  10. * any later version. See COPYING for more details.
  11. */
  12. #include "config.h"
  13. #include <limits.h>
  14. #include <pthread.h>
  15. #include <stdint.h>
  16. #include <stdio.h>
  17. #include <strings.h>
  18. #include <sys/time.h>
  19. #include <unistd.h>
  20. #include <math.h>
  21. #ifndef WIN32
  22. #include <sys/select.h>
  23. #include <termios.h>
  24. #include <sys/stat.h>
  25. #include <fcntl.h>
  26. #else
  27. #include "compat.h"
  28. #include <windows.h>
  29. #include <winsock2.h>
  30. #include <io.h>
  31. #endif /* WIN32 */
  32. #include "miner.h"
  33. #include "usbutils.h"
  34. #include "fpgautils.h"
  35. #include "elist.h"
  36. #include "util.h"
  37. #include "driver-gridseed.h"
  38. #define using_libusb(info) ((info)->using_libusb > 0)
  39. #define using_serial(info) ((info)->using_libusb == 0)
  40. static const char *gridseed_version = "v3.8.5.20140210.02";
  41. static const char *str_reset[] = {
  42. "55AAC000808080800000000001000000", // Chip reset
  43. "55AAC000E0E0E0E00000000001000000", // FW reset
  44. NULL
  45. };
  46. static const char *str_init[] = {
  47. "55AAC000C0C0C0C00500000001000000",
  48. "55AAEF020000000000000000000000000000000000000000",
  49. "55AAEF3020000000",
  50. NULL
  51. };
  52. static const char *str_ltc_reset[] = {
  53. "55AA1F2817000000",
  54. "55AA1F2814000000",
  55. "55AA1F2817000000",
  56. NULL
  57. };
  58. static const char *str_nofifo[] = {
  59. "55AAC000D0D0D0D00000000001000000",
  60. NULL
  61. };
  62. #ifdef WIN32
  63. static void __maybe_unused set_text_color(WORD color)
  64. {
  65. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
  66. }
  67. #endif
  68. #ifdef WIN32
  69. static char *win32strerror(DWORD err)
  70. {
  71. static char errstr[256];
  72. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
  73. NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errstr, sizeof(errstr), NULL);
  74. return errstr;
  75. }
  76. #endif
  77. #ifdef WIN32
  78. #define sockclose(sock) closesocket(sock)
  79. #define sockerror(err) ((err) == SOCKET_ERROR)
  80. #define sockerrorstr() win32strerror(WSAGetLastError())
  81. #else
  82. #define sockclose(sock) close(sock)
  83. #define sockerror(err) ((err) < 0)
  84. #define sockerrorstr() strerror(errno)
  85. #endif
  86. // Unset upon first hotplug check
  87. static bool initial_startup_phase = true;
  88. /*---------------------------------------------------------------------------------------*/
  89. static int gridseed_send_ping_packet(GRIDSEED_INFO *, struct sockaddr_in);
  90. static void *gridseed_recv_packet(void *);
  91. static void gc3355_send_cmds(struct cgpu_info *, const char **);
  92. static bool gridseed_send_work_usb(struct cgpu_info *, unsigned char *, unsigned char *,
  93. unsigned char *, int, enum gsd_mode);
  94. static void __gridseed_test_ltc_nonce(struct cgpu_info *, GRIDSEED_INFO *,
  95. struct thr_info *, uint32_t, unsigned int);
  96. static int check_udp_port_in_use(short port)
  97. {
  98. int sock;
  99. struct sockaddr_in local;
  100. sock = socket(AF_INET, SOCK_DGRAM, 0);
  101. #ifndef WIN32
  102. if (sock < 0)
  103. return -1;
  104. #else
  105. if ((unsigned int)sock == INVALID_SOCKET)
  106. return -1;
  107. #endif
  108. local.sin_family = AF_INET;
  109. local.sin_port = htons(port);
  110. local.sin_addr.s_addr = inet_addr("127.0.0.1");
  111. if (sockerror(bind(sock, (struct sockaddr*)&local, sizeof(local)))) {
  112. sockclose(sock);
  113. return -1;
  114. }
  115. return sock;
  116. }
  117. static void gridseed_create_proxy(struct cgpu_info *gridseed, GRIDSEED_INFO *info)
  118. {
  119. int sock = info->sockltc;
  120. short port = info->ltc_port;
  121. if (sock != -1)
  122. sockclose(sock);
  123. info->sockltc = -1;
  124. while (true) {
  125. sock = check_udp_port_in_use(port);
  126. if (sock > -1)
  127. break;
  128. port++;
  129. }
  130. info->sockltc = sock;
  131. info->ltc_port = port;
  132. applog(LOG_NOTICE, "Create scrypt proxy on %d/UDP for %s%d", info->ltc_port, gridseed->drv->name, gridseed->device_id);
  133. }
  134. static bool gridseed_find_proxy(GRIDSEED_INFO *info)
  135. {
  136. struct sockaddr_in remote;
  137. struct timeval tv_timeout;
  138. GRIDSEED_PACKET packet;
  139. fd_set rdfs;
  140. int addrlen, n, sock = info->sockltc;
  141. short port = info->ltc_port + 1000;
  142. if (sock != -1)
  143. sockclose(sock);
  144. info->sockltc = -1;
  145. while (true) {
  146. sock = check_udp_port_in_use(port);
  147. if (sock > -1)
  148. break;
  149. port++;
  150. }
  151. info->ltc_port = port - 1000;
  152. info->sockltc = sock;
  153. remote.sin_family = AF_INET;
  154. remote.sin_port = htons(info->ltc_port);
  155. remote.sin_addr.s_addr = inet_addr("127.0.0.1");
  156. applog(LOG_INFO, "Checking for scrypt proxy on %d/UDP", info->ltc_port);
  157. if (gridseed_send_ping_packet(info, remote) != 0) {
  158. sockclose(sock);
  159. return false;
  160. }
  161. tv_timeout.tv_sec = 0;
  162. tv_timeout.tv_usec = 500000;
  163. FD_ZERO(&rdfs);
  164. FD_SET(sock, &rdfs);
  165. if (select(sock+1, &rdfs, NULL, NULL, &tv_timeout) != 1) {
  166. sockclose(sock);
  167. return false;
  168. }
  169. addrlen = sizeof(remote);
  170. n = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr *)&remote, (socklen_t *)&addrlen);
  171. if (sockerror(n) || n != sizeof(packet)) {
  172. sockclose(sock);
  173. return false;
  174. }
  175. if (gridseed_send_ping_packet(info, remote) != 0) {
  176. sockclose(sock);
  177. return false;
  178. }
  179. //if (cgsem_mswait(&info->psem, 500) != 0)
  180. // return false;
  181. applog(LOG_NOTICE, "Found scrypt proxy on %d/UDP", info->ltc_port);
  182. return true;
  183. }
  184. static int gridseed_send_ping_packet(GRIDSEED_INFO *info, struct sockaddr_in to)
  185. {
  186. GRIDSEED_PACKET packet;
  187. if (info->sockltc < 0)
  188. return -1;
  189. packet.type = PACKET_PING;
  190. if (sendto(info->sockltc, (char*)&packet, sizeof(packet), 0, (struct sockaddr *)&to,
  191. sizeof(to)) != sizeof(packet)) {
  192. applog(LOG_WARNING, "Couldn't send ping packet: %s", sockerrorstr());
  193. return -1;
  194. }
  195. return 0;
  196. }
  197. static int gridseed_send_info_packet(GRIDSEED_INFO *info, struct sockaddr_in to)
  198. {
  199. GRIDSEED_PACKET packet;
  200. if (info->sockltc < 0)
  201. return -1;
  202. packet.type = PACKET_INFO;
  203. packet.info.freq = info->freq;
  204. packet.info.chips = info->chips;
  205. packet.info.modules = info->modules;
  206. strncpy(packet.info.id, info->id, sizeof(packet.info.id));
  207. if (sendto(info->sockltc, (char*)&packet, sizeof(packet), 0, (struct sockaddr *)&to,
  208. sizeof(to)) != sizeof(packet)) {
  209. applog(LOG_WARNING, "Couldn't send info packet: %s", sockerrorstr());
  210. return -1;
  211. }
  212. return 0;
  213. }
  214. static void gridseed_recv_info_packet(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  215. GRIDSEED_PACKET packet, struct sockaddr_in from)
  216. {
  217. mutex_lock(&info->qlock);
  218. info->freq = packet.info.freq;
  219. info->chips = packet.info.chips;
  220. info->modules = packet.info.modules;
  221. strncpy(info->id, packet.info.id, sizeof(info->id));
  222. gridseed->unique_id = info->id;
  223. info->toaddr = from;
  224. mutex_unlock(&info->qlock);
  225. cgsem_post(&info->psem);
  226. }
  227. static bool gridseed_send_work_packet(GRIDSEED_INFO *info, struct work *work)
  228. {
  229. GRIDSEED_PACKET packet;
  230. if (info->sockltc < 0)
  231. return false;
  232. packet.type = PACKET_WORK;
  233. memcpy(packet.work.target, work->target, sizeof(packet.work.target));
  234. memcpy(packet.work.midstate, work->midstate, sizeof(packet.work.midstate));
  235. memcpy(packet.work.data, work->data, sizeof(packet.work.data));
  236. packet.work.id = work->id;
  237. if (sendto(info->sockltc, (char*)&packet, sizeof(packet), 0,
  238. (struct sockaddr *)&(info->toaddr), sizeof(info->toaddr)) != sizeof(packet)) {
  239. applog(LOG_WARNING, "Couldn't send work packet: %s", sockerrorstr());
  240. return false;
  241. }
  242. return true;
  243. }
  244. static void gridseed_recv_work_packet(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  245. GRIDSEED_PACKET packet, struct sockaddr_in from)
  246. {
  247. mutex_lock(&info->qlock);
  248. info->toaddr = from;
  249. gridseed_send_work_usb(gridseed, packet.work.target, packet.work.midstate,
  250. packet.work.data, packet.work.id, MODE_SCRYPT_DUAL);
  251. mutex_unlock(&info->qlock);
  252. }
  253. static int gridseed_send_nonce_packet(GRIDSEED_INFO *info, unsigned char *data)
  254. {
  255. GRIDSEED_PACKET packet;
  256. uint32_t nonce;
  257. int workid;
  258. if (info->sockltc < 0)
  259. return -1;
  260. memcpy(&workid, data+8, 4);
  261. memcpy(&nonce, data+4, 4);
  262. packet.type = PACKET_NONCE;
  263. packet.nonce.nonce = nonce;
  264. packet.nonce.workid = workid;
  265. if (sendto(info->sockltc, (char*)&packet, sizeof(packet), 0, (struct sockaddr *)&(info->toaddr),
  266. sizeof(info->toaddr)) != sizeof(packet)) {
  267. applog(LOG_WARNING, "Couldn't send nonce packet: %s", sockerrorstr());
  268. return -1;
  269. }
  270. return 0;
  271. }
  272. static void gridseed_recv_nonce_packet(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  273. GRIDSEED_PACKET packet)
  274. {
  275. __gridseed_test_ltc_nonce(gridseed, info, info->thr, packet.nonce.nonce, packet.nonce.workid);
  276. }
  277. static void *gridseed_recv_packet(void *userdata)
  278. {
  279. struct cgpu_info *gridseed = (struct cgpu_info *)userdata;
  280. GRIDSEED_INFO *info = gridseed->device_data;
  281. GRIDSEED_PACKET packet;
  282. struct timeval ts_packet, ts_now, tv_timeout;
  283. struct sockaddr_in fromaddr;
  284. fd_set rdfs;
  285. char threadname[24];
  286. int addrlen, n, no_packets = 0, sock = info->sockltc;
  287. snprintf(threadname, sizeof(threadname), "GridSeed_Packet/%d", gridseed->device_id);
  288. RenameThread(threadname);
  289. applog(LOG_INFO, "GridSeed: packet thread running, %s", threadname);
  290. cgtime(&ts_packet); // initialize
  291. while(likely(!gridseed->shutdown)) {
  292. cgtime(&ts_now);
  293. if (info->mode == MODE_SCRYPT_DUAL &&
  294. tdiff(&ts_now, &ts_packet) > (120 + 60 * no_packets)) {
  295. if (no_packets > 5) {
  296. applog(LOG_ERR, "%s%d: Proxy not responding, shutting down",
  297. gridseed->drv->name, gridseed->device_id);
  298. gridseed->shutdown = true;
  299. break;
  300. } else {
  301. applog(LOG_NOTICE, "%s%d: No data from proxy, sending ping",
  302. gridseed->drv->name, gridseed->device_id);
  303. gridseed_send_ping_packet(info, info->toaddr);
  304. }
  305. no_packets++;
  306. } else if (info->mode == MODE_SHA256_DUAL &&
  307. tdiff(&ts_now, &ts_packet) > 130) {
  308. info->mode = MODE_SHA256;
  309. mutex_lock(&info->qlock);
  310. gc3355_send_cmds(gridseed, str_ltc_reset);
  311. cgsleep_ms(50);
  312. mutex_unlock(&info->qlock);
  313. }
  314. tv_timeout.tv_sec = 2;
  315. tv_timeout.tv_usec = 0;
  316. FD_ZERO(&rdfs);
  317. FD_SET(sock, &rdfs);
  318. n = select(sock+1, &rdfs, NULL, NULL, &tv_timeout);
  319. if (n == 0)
  320. continue;
  321. if (n < 0) {
  322. if (errno == EINTR)
  323. continue;
  324. applog(LOG_ERR, "Error calling select: %s", sockerrorstr());
  325. gridseed->shutdown = true;
  326. break;
  327. }
  328. addrlen = sizeof(fromaddr);
  329. n = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr *)&fromaddr, (socklen_t *)&addrlen);
  330. if (sockerror(n)) {
  331. if (errno == EINTR)
  332. continue;
  333. applog(LOG_ERR, "Error calling recvfrom: %s", sockerrorstr());
  334. gridseed->shutdown = true;
  335. break;
  336. }
  337. if (n != sizeof(packet))
  338. continue;
  339. cgtime(&ts_packet);
  340. switch (packet.type) {
  341. case PACKET_PING:
  342. if (!SHA256_MODE(info->mode))
  343. break;
  344. gridseed_send_info_packet(info, fromaddr);
  345. applog(LOG_INFO, "Received ping packet");
  346. break;
  347. case PACKET_INFO:
  348. if (!SCRYPT_MODE(info->mode))
  349. break;
  350. gridseed_recv_info_packet(gridseed, info, packet, fromaddr);
  351. applog(LOG_INFO, "Received info packet");
  352. break;
  353. case PACKET_WORK:
  354. if (!SHA256_MODE(info->mode))
  355. break;
  356. info->mode = MODE_SHA256_DUAL;
  357. gridseed_recv_work_packet(gridseed, info, packet, fromaddr);
  358. applog(LOG_INFO, "Received work packet");
  359. break;
  360. case PACKET_NONCE:
  361. if (!SCRYPT_MODE(info->mode))
  362. break;
  363. gridseed_recv_nonce_packet(gridseed, info, packet);
  364. applog(LOG_INFO, "Received nonce packet");
  365. break;
  366. default:
  367. applog(LOG_ERR, "Received unknown packet");
  368. break;
  369. }
  370. }
  371. return NULL;
  372. }
  373. /*---------------------------------------------------------------------------------------*/
  374. /************************************************************
  375. * Utility Functions
  376. ************************************************************/
  377. static void flush_uart(int fd)
  378. {
  379. #ifdef WIN32
  380. const HANDLE fh = (HANDLE)_get_osfhandle(fd);
  381. PurgeComm(fh, PURGE_RXCLEAR);
  382. #else
  383. tcflush(fd, TCIFLUSH);
  384. #endif
  385. }
  386. static void _transfer(struct cgpu_info *gridseed, uint8_t request_type, uint8_t bRequest,
  387. uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, enum usb_cmds cmd)
  388. {
  389. int err;
  390. err = usb_transfer_data(gridseed, request_type, bRequest, wValue, wIndex, data, siz, cmd);
  391. cgsleep_ms(GRIDSEED_COMMAND_DELAY);
  392. applog(LOG_DEBUG, "%s: cgid %d %s got err %d",
  393. gridseed->drv->name, gridseed->cgminer_id,
  394. usb_cmdname(cmd), err);
  395. }
  396. /************************************************************
  397. * I/O helper functions
  398. ************************************************************/
  399. #define gridseed_serial_open_detect(devpath, baud, purge) serial_open_ex(devpath, baud, 2, 0, purge, true)
  400. #define gridseed_serial_open(devpath, baud, purge) serial_open_ex(devpath, baud, 2, 0, purge, true)
  401. #define gridseed_serial_close(fd) close(fd)
  402. static bool gridseed_reopen(struct cgpu_info *gridseed)
  403. {
  404. GRIDSEED_INFO *info = gridseed->device_data;
  405. int try, fd = -1;
  406. if (!using_serial(info)) // sanity check
  407. return false;
  408. if (info->device_fd != -1) {
  409. applog(LOG_DEBUG, "Closing %s%d on %s (fd=%d)",
  410. gridseed->drv->name, gridseed->device_id, gridseed->device_path, info->device_fd);
  411. gridseed_serial_close(info->device_fd);
  412. info->device_fd = -1;
  413. cgsleep_ms(2000);
  414. }
  415. applog(LOG_DEBUG, "Attempting to open %s%d on %s",
  416. gridseed->drv->name, gridseed->device_id, gridseed->device_path);
  417. for (try = 0; try < 3; ++try) {
  418. fd = gridseed_serial_open(gridseed->device_path, info->baud, true);
  419. if (likely(fd > -1))
  420. break;
  421. cgsleep_ms(3000);
  422. }
  423. if (unlikely(fd < 0)) {
  424. applog(LOG_ERR, "Failed to open %s%d on %s (%d attempts)",
  425. gridseed->drv->name, gridseed->device_id, gridseed->device_path, try);
  426. return false;
  427. }
  428. info->device_fd = fd;
  429. applog(LOG_DEBUG, "Successfully opened %s%d on %s (%d attempts, fd=%d)",
  430. gridseed->drv->name, gridseed->device_id, gridseed->device_path, try, info->device_fd);
  431. return true;
  432. }
  433. static int gc3355_write(struct cgpu_info *gridseed, const void *buf, size_t len)
  434. {
  435. GRIDSEED_INFO *info = gridseed->device_data;
  436. int ret, err;
  437. if (opt_debug) {
  438. char *hexstr;
  439. hexstr = bin2hex(buf, len);
  440. applog(LOG_DEBUG, "> %s", hexstr);
  441. free(hexstr);
  442. }
  443. #if 0
  444. if (!opt_quiet && opt_debug) {
  445. int i;
  446. #ifndef WIN32
  447. fprintf(stderr, " >>> %d : ", size);
  448. #else
  449. set_text_color(FOREGROUND_RED|FOREGROUND_GREEN);
  450. fprintf(stderr, " >>> %d : ", size);
  451. set_text_color(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
  452. #endif
  453. for(i=0; i<size; i++) {
  454. fprintf(stderr, "%02x", data[i]);
  455. if (i==3)
  456. fprintf(stderr, " ");
  457. }
  458. fprintf(stderr, "\n");
  459. }
  460. #endif
  461. if (using_libusb(info)) {
  462. err = usb_write(gridseed, (char *)buf, len, &ret, C_SENDWORK);
  463. if (err != LIBUSB_SUCCESS) {
  464. applog(LOG_ERR, "%s%d: error on USB write: %s",
  465. gridseed->drv->name, gridseed->device_id, libusb_strerror(err));
  466. return -1;
  467. } else if (ret < 0 || (size_t)ret != len) {
  468. applog(LOG_ERR, "%s%d: usb_write length mismatch: %zu != %d",
  469. gridseed->drv->name, gridseed->device_id, len, ret);
  470. return -1;
  471. }
  472. } else {
  473. #ifndef WIN32
  474. ret = write(info->device_fd, buf, len);
  475. #else
  476. ret = win32write(info->device_fd, buf, len);
  477. #endif
  478. if (ret < 0) {
  479. applog(LOG_ERR, "%s%d: error on serial write (fd=%d): %s",
  480. gridseed->drv->name, gridseed->device_id, info->device_fd, strerror(errno));
  481. info->serial_reopen = true;
  482. return -1;
  483. }
  484. }
  485. cgsleep_ms(GRIDSEED_COMMAND_DELAY);
  486. return ret;
  487. }
  488. #define gc3355_get_data(gridseed, buf, len) gc3355_read(gridseed, buf, len, 1)
  489. static int gc3355_read(struct cgpu_info *gridseed, void *buf, size_t len, int read_count)
  490. {
  491. GRIDSEED_INFO *info = gridseed->device_data;
  492. ssize_t ret;
  493. size_t total = 0;
  494. int err, rc = 0;
  495. while (total < len) {
  496. if (using_libusb(info)) {
  497. err = usb_read_once_timeout(gridseed, (char *)buf + total, len - total, (int*)&ret, 200, C_GETRESULTS);
  498. if (err != LIBUSB_SUCCESS && err != LIBUSB_ERROR_TIMEOUT) {
  499. applog(LOG_ERR, "%s%d: error on USB read: %s",
  500. gridseed->drv->name, gridseed->device_id, libusb_strerror(err));
  501. return -1;
  502. }
  503. } else {
  504. #ifndef WIN32
  505. ret = read(info->device_fd, buf + total, len - total);
  506. #else
  507. ret = win32read(info->device_fd, buf + total, len - total);
  508. #endif
  509. if (ret < 0) {
  510. applog(LOG_ERR, "%s%d: error on serial read (fd=%d): %s",
  511. gridseed->drv->name, gridseed->device_id, info->device_fd, strerror(errno));
  512. info->serial_reopen = true;
  513. return -1;
  514. }
  515. }
  516. if (ret == 0 && ++rc >= read_count)
  517. break;
  518. total += (size_t)ret;
  519. }
  520. if (opt_debug) {
  521. char *hexstr;
  522. if (total > 0) {
  523. hexstr = bin2hex(buf, total);
  524. applog(LOG_DEBUG, "< %s", hexstr);
  525. free(hexstr);
  526. } else {
  527. applog(LOG_DEBUG, "< (no data)");
  528. }
  529. }
  530. #if 0
  531. if (!opt_quiet && opt_debug) {
  532. int i;
  533. #ifndef WIN32
  534. fprintf(stderr, " <<< %d : ", offset);
  535. #else
  536. set_text_color(FOREGROUND_RED);
  537. fprintf(stderr, " <<< %d : ", offset);
  538. set_text_color(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
  539. #endif
  540. for(i = 0; i < offset; i++) {
  541. fprintf(stderr, "%02x", buf[i]);
  542. if ((i+1) % 4 == 0)
  543. fprintf(stderr, " ");
  544. }
  545. fprintf(stderr, "\n");
  546. }
  547. #endif
  548. return total;
  549. }
  550. static void gc3355_send_cmds(struct cgpu_info *gridseed, const char *cmds[])
  551. {
  552. unsigned char ob[512];
  553. int i;
  554. for(i=0; cmds[i] != NULL; i++) {
  555. hex2bin(ob, cmds[i], sizeof(ob));
  556. gc3355_write(gridseed, ob, strlen(cmds[i])/2);
  557. }
  558. }
  559. static void gc3355_send_cmds_bin(struct cgpu_info *gridseed, const char *cmds[], int size)
  560. {
  561. int i;
  562. for(i=0; cmds[i] != NULL; i++) {
  563. gc3355_write(gridseed, (unsigned char *)cmds[i], size);
  564. }
  565. }
  566. static bool gc3355_read_register(struct cgpu_info *gridseed, uint32_t reg_addr,
  567. uint32_t *reg_value) {
  568. GRIDSEED_INFO *info = (GRIDSEED_INFO*)(gridseed->device_data);
  569. unsigned char cmd[16] = "\x55\xaa\xc0\x01";
  570. uint32_t reg_len = 4;
  571. unsigned char buf[4];
  572. if (info->fw_version != 0x01140113) {
  573. applog(LOG_ERR, "Can't read registers; incompatible firmware %08X on %s%d",
  574. info->fw_version, gridseed->drv->name, gridseed->device_id);
  575. return false;
  576. }
  577. *(uint32_t *)(cmd + 4) = htole32(reg_addr);
  578. *(uint32_t *)(cmd + 8) = htole32(reg_len);
  579. *(uint32_t *)(cmd + 12) = htole32(reg_len);
  580. if (gc3355_write(gridseed, cmd, sizeof(cmd)) != sizeof(cmd)) {
  581. applog(LOG_DEBUG, "Failed to write data to %s%d", gridseed->drv->name, gridseed->device_id);
  582. return false;
  583. }
  584. if (gc3355_get_data(gridseed, buf, 4) != 4) {
  585. applog(LOG_DEBUG, "No response from %s%d", gridseed->drv->name, gridseed->device_id);
  586. return false;
  587. }
  588. *reg_value = le32toh(*(uint32_t *)buf);
  589. return true;
  590. }
  591. static bool gc3355_write_register(struct cgpu_info *gridseed, uint32_t reg_addr,
  592. uint32_t reg_value) {
  593. GRIDSEED_INFO *info = (GRIDSEED_INFO*)(gridseed->device_data);
  594. unsigned char cmd[16] = "\x55\xaa\xc0\x02";
  595. uint32_t reg_len = 4;
  596. unsigned char buf[4];
  597. if (info->fw_version != 0x01140113) {
  598. applog(LOG_ERR, "Can't write registers; incompatible firmware %08X on %s%d",
  599. info->fw_version, gridseed->drv->name, gridseed->device_id);
  600. return false;
  601. }
  602. *(uint32_t *)(cmd + 4) = htole32(reg_addr);
  603. *(uint32_t *)(cmd + 8) = htole32(reg_value);
  604. *(uint32_t *)(cmd + 12) = htole32(reg_len);
  605. if (gc3355_write(gridseed, cmd, sizeof(cmd)) != sizeof(cmd)) {
  606. applog(LOG_DEBUG, "Failed to write data to %s%d", gridseed->drv->name, gridseed->device_id);
  607. return false;
  608. }
  609. if (gc3355_get_data(gridseed, buf, 4) != 4) {
  610. applog(LOG_DEBUG, "No response from %s%d", gridseed->drv->name, gridseed->device_id);
  611. return false;
  612. }
  613. return true;
  614. }
  615. static void gc3355_switch_leds(struct cgpu_info *gridseed) {
  616. uint32_t reg_value;
  617. // Set GPIOB pins 0 and 1 as general purpose output, open-drain, 50 MHz max
  618. if (!gc3355_read_register(gridseed, GRIDSEED_GPIOB_BASE + GRIDSEED_CRL_OFFSET, &reg_value)) {
  619. applog(LOG_DEBUG, "Failed to read GPIOA CRL register from %i", gridseed->device_id);
  620. return;
  621. }
  622. reg_value = (reg_value & 0xffffff00) | 0x00000077;
  623. if (!gc3355_write_register(gridseed, GRIDSEED_GPIOB_BASE + GRIDSEED_CRL_OFFSET, reg_value)) {
  624. applog(LOG_DEBUG, "Failed to write GPIOA CRL register from %i", gridseed->device_id);
  625. return;
  626. }
  627. applog(LOG_NOTICE, "%s%d: Turned off GC3355 LEDs",
  628. gridseed->drv->name, gridseed->device_id);
  629. }
  630. static void gc3355_switch_voltage(struct cgpu_info *gridseed) {
  631. uint32_t reg_value;
  632. // Put GPIOA pin 5 into general function, 50 MHz output.
  633. if (!gc3355_read_register(gridseed, GRIDSEED_GPIOA_BASE + GRIDSEED_CRL_OFFSET, &reg_value)) {
  634. applog(LOG_DEBUG, "Failed to read GPIOA CRL register from %s%d", gridseed->drv->name, gridseed->device_id);
  635. return;
  636. }
  637. reg_value = (reg_value & 0xff0fffff) | 0x00300000;
  638. if (!gc3355_write_register(gridseed, GRIDSEED_GPIOA_BASE + GRIDSEED_CRL_OFFSET, reg_value)) {
  639. applog(LOG_DEBUG, "Failed to write GPIOA CRL register from %s%d", gridseed->drv->name, gridseed->device_id);
  640. return;
  641. }
  642. // Set GPIOA pin 5 high.
  643. if (!gc3355_read_register(gridseed, GRIDSEED_GPIOA_BASE + GRIDSEED_ODR_OFFSET, &reg_value)) {
  644. applog(LOG_DEBUG, "Failed to read GPIOA ODR register from %s%d", gridseed->drv->name, gridseed->device_id);
  645. return;
  646. }
  647. reg_value |= 0x00000020;
  648. if (!gc3355_write_register(gridseed, GRIDSEED_GPIOA_BASE + GRIDSEED_ODR_OFFSET, reg_value)) {
  649. applog(LOG_DEBUG, "Failed to write GPIOA ODR register from %s%d", gridseed->drv->name, gridseed->device_id);
  650. return;
  651. }
  652. applog(LOG_NOTICE, "%s%d: Switched GC3355 voltage to alternate voltage",
  653. gridseed->drv->name, gridseed->device_id);
  654. }
  655. static void gc3355_set_init_nonce(struct cgpu_info *gridseed)
  656. {
  657. GRIDSEED_INFO *info;
  658. int i;
  659. char **cmds, *p;
  660. uint32_t nonce, step;
  661. info = (GRIDSEED_INFO*)(gridseed->device_data);
  662. cmds = calloc(sizeof(char*)*(info->chips+1), 1);
  663. if (unlikely(!cmds))
  664. quit(1, "Failed to calloc init nonce commands data array");
  665. step = 0xffffffff / info->chips;
  666. for(i=0; i<info->chips; i++) {
  667. p = calloc(8, 1);
  668. if (unlikely(!p))
  669. quit(1, "Failed to calloc init nonce commands data");
  670. memcpy(p, "\x55\xaa\x00\x00", 4);
  671. p[2] = i;
  672. nonce = htole32(step*i);
  673. memcpy(p+4, &nonce, sizeof(nonce));
  674. cmds[i] = p;
  675. }
  676. cmds[i] = NULL;
  677. gc3355_send_cmds_bin(gridseed, (const char **)cmds, 8);
  678. for(i=0; i<info->chips; i++)
  679. free(cmds[i]);
  680. free(cmds);
  681. }
  682. static void gc3355_enable_btc_cores(struct cgpu_info *gridseed, GRIDSEED_INFO *info)
  683. {
  684. unsigned char cmd[24], c1, c2;
  685. uint16_t mask;
  686. int i;
  687. mask = 0x00;
  688. for(i=0; i<info->btcore; i++)
  689. mask = mask << 1 | 0x01;
  690. if (mask == 0)
  691. return;
  692. c1 = mask & 0x00ff;
  693. c2 = mask >> 8;
  694. memset(cmd, 0, sizeof(cmd));
  695. memcpy(cmd, "\x55\xAA\xEF\x02", 4);
  696. for(i=4; i<24; i++) {
  697. cmd[i] = ((i%2)==0) ? c1 : c2;
  698. gc3355_write(gridseed, cmd, sizeof(cmd));
  699. }
  700. }
  701. static void gc3355_set_core_freq(struct cgpu_info *gridseed)
  702. {
  703. GRIDSEED_INFO *info = (GRIDSEED_INFO*)(gridseed->device_data);
  704. gc3355_write(gridseed, info->cmd_freq, sizeof(info->cmd_freq));
  705. if (SHA256_MODE(info->mode)) {
  706. gc3355_write(gridseed, info->cmd_btc_baud, sizeof(info->cmd_btc_baud));
  707. }
  708. applog(LOG_NOTICE, "%s%d: Set GC3355 core frequency to %d MHz",
  709. gridseed->drv->name, gridseed->device_id, info->freq);
  710. }
  711. static void gc3355_init(struct cgpu_info *gridseed, GRIDSEED_INFO *info)
  712. {
  713. char buf[512];
  714. int amount;
  715. applog(LOG_NOTICE, "%s%d: System reseting", gridseed->drv->name, gridseed->device_id);
  716. gc3355_send_cmds(gridseed, str_reset);
  717. cgsleep_ms(200);
  718. if (using_libusb(info)) {
  719. usb_buffer_clear(gridseed);
  720. usb_read_timeout(gridseed, buf, sizeof(buf), &amount, 10, C_GETRESULTS);
  721. } else {
  722. flush_uart(info->device_fd);
  723. }
  724. gc3355_send_cmds(gridseed, str_init);
  725. gc3355_send_cmds(gridseed, str_ltc_reset);
  726. gc3355_set_core_freq(gridseed);
  727. if (SHA256_MODE(info->mode)) {
  728. gc3355_set_init_nonce(gridseed);
  729. gc3355_enable_btc_cores(gridseed, info);
  730. if (info->usefifo == 0)
  731. gc3355_send_cmds(gridseed, str_nofifo);
  732. }
  733. if (info->voltage)
  734. gc3355_switch_voltage(gridseed);
  735. if (info->led)
  736. gc3355_switch_leds(gridseed);
  737. }
  738. static void set_freq_cmd(GRIDSEED_INFO *info, int pll_r, int pll_f, int pll_od)
  739. {
  740. if (pll_r == 0 && pll_f == 0 && pll_od == 0) {
  741. // Support frequency increments of 12.5 MHz
  742. // Non-integer frequencies must be specified rounded up
  743. // With these values the minimum we can set is 12.5 and the max 1600
  744. pll_r = 1;
  745. pll_f = 2 * info->freq / GRIDSEED_F_IN - 1;
  746. pll_f = MAX(0, MIN(127, pll_f));
  747. }
  748. double f_ref = GRIDSEED_F_IN / (pll_r + 1.);
  749. double f_vco = f_ref * (pll_f + 1.);
  750. double f_out = f_vco / (1 << pll_od);
  751. int pll_bs = (f_out >= 500.) ? 1 : 0;
  752. int cfg_pm = 1, pll_clk_gate = 1;
  753. uint32_t cmdf = (cfg_pm << 0) | (pll_clk_gate << 2) | (pll_r << 16) |
  754. (pll_f << 21) | (pll_od << 28) | (pll_bs << 31);
  755. info->freq = (int)ceil(f_out);
  756. memcpy(info->cmd_freq, "\x55\xaa\xef\x00", 4);
  757. // *(uint32_t *)(info->cmd_freq + 4) = htole32(cmdf);
  758. cmdf = htole32(cmdf);
  759. memcpy(info->cmd_freq + 4, &cmdf, 4);
  760. uint32_t cmdb = 0x40000000 | ((uint32_t)round(f_out * 1000000. / info->baud) & 0xffff);
  761. cmdb = htole32(cmdb);
  762. memcpy(info->cmd_btc_baud, "\x55\xaa\x0f\xff", 4);
  763. memcpy(info->cmd_btc_baud + 4, &cmdb, 4);
  764. }
  765. static bool get_options(GRIDSEED_INFO *info, const char *options)
  766. {
  767. char *ss, *p, *end, *comma, *eq;
  768. int tmp, pll_r = 0, pll_f = 0, pll_od = 0;
  769. if (options == NULL)
  770. return false;
  771. //applog(LOG_NOTICE, "GridSeed options: '%s'", options);
  772. ss = strdup(options);
  773. p = ss;
  774. end = p + strlen(p);
  775. another:
  776. comma = strchr(p, ',');
  777. if (comma != NULL)
  778. *comma = '\0';
  779. eq = strchr(p, '=');
  780. if (eq == NULL)
  781. goto next;
  782. *eq = '\0';
  783. tmp = atoi(eq+1);
  784. if (strcasecmp(p, "baud")==0) {
  785. info->baud = (tmp != 0) ? tmp : info->baud;
  786. }
  787. else if (strcasecmp(p, "freq")==0) {
  788. info->freq = tmp;
  789. }
  790. else if (strcasecmp(p, "pll_r")==0) {
  791. pll_r = (tmp != 0) ? tmp : pll_r;
  792. pll_r = MAX(0, MIN(31, pll_r));
  793. }
  794. else if (strcasecmp(p, "pll_f")==0) {
  795. pll_f = (tmp != 0) ? tmp : pll_f;
  796. pll_f = MAX(0, MIN(127, pll_f));
  797. }
  798. else if (strcasecmp(p, "pll_od")==0) {
  799. pll_od = (tmp != 0) ? tmp : pll_od;
  800. pll_od = MAX(0, MIN(4, pll_od));
  801. }
  802. else if (strcasecmp(p, "chips")==0) {
  803. info->chips = (tmp != 0) ? tmp : info->chips;
  804. info->chips = MAX(0, MIN(GRIDSEED_MAX_CHIPS, info->chips));
  805. }
  806. else if (strcasecmp(p, "modules")==0) {
  807. info->modules = (tmp != 0) ? tmp : info->modules;
  808. }
  809. else if (strcasecmp(p, "usefifo")==0) {
  810. info->usefifo = tmp;
  811. }
  812. else if (strcasecmp(p, "btc")==0) {
  813. info->btcore = tmp;
  814. }
  815. else if (strcasecmp(p, "voltage")==0) {
  816. info->voltage = (tmp != 0) ? tmp : info->voltage;
  817. }
  818. else if (strcasecmp(p, "led_off")==0) {
  819. info->led = (tmp != 0) ? tmp : info->led;
  820. }
  821. else if (strcasecmp(p, "per_chip_stats")==0) {
  822. info->per_chip_stats = (tmp != 0) ? tmp : info->per_chip_stats;
  823. }
  824. else if (strcasecmp(p, "start_port")==0) {
  825. info->ltc_port = tmp;
  826. }
  827. next:
  828. if (comma != NULL) {
  829. p = comma + 1;
  830. if (p < end)
  831. goto another;
  832. }
  833. free(ss);
  834. set_freq_cmd(info, pll_r, pll_f, pll_od);
  835. return true;
  836. }
  837. static bool get_freq(GRIDSEED_INFO *info, const char *options, const char *id)
  838. {
  839. char *ss, *p, *end, *comma, *eq;
  840. int tmp;
  841. if (options == NULL)
  842. return false;
  843. applog(LOG_NOTICE, "GridSeed freq options: '%s'", options);
  844. ss = strdup(options);
  845. p = ss;
  846. end = p + strlen(p);
  847. another:
  848. comma = strchr(p, ',');
  849. if (comma != NULL)
  850. *comma = '\0';
  851. eq = strchr(p, '=');
  852. if (eq == NULL)
  853. goto next;
  854. *eq = '\0';
  855. tmp = atoi(eq+1);
  856. if (strcasecmp(p, id) == 0) {
  857. info->freq = tmp;
  858. set_freq_cmd(info, 0, 0, 0);
  859. if (info->freq == tmp)
  860. applog(LOG_INFO, "%s unique frequency: %i MHz", p, info->freq);
  861. else
  862. applog(LOG_NOTICE, "%s unique frequency: requested %i MHz, using instead %i MHz", p, tmp, info->freq);
  863. }
  864. next:
  865. if (comma != NULL) {
  866. p = comma + 1;
  867. if (p < end)
  868. goto another;
  869. }
  870. free(ss);
  871. return true;
  872. }
  873. static bool get_override(GRIDSEED_INFO *info, const char *options, const char *id)
  874. {
  875. char *ss, *p, *colon, *semi;
  876. bool ret = false;
  877. if (options == NULL)
  878. return false;
  879. ss = strdup(options);
  880. p = ss;
  881. do {
  882. semi = strchr(p, ';');
  883. if (semi != NULL)
  884. *semi = '\0';
  885. colon = strchr(p, ':');
  886. if (colon == NULL)
  887. continue;
  888. *colon = '\0';
  889. if (strcasecmp(p, id) == 0) {
  890. ret = get_options(info, colon + 1);
  891. break;
  892. }
  893. } while (semi != NULL && (p = semi + 1));
  894. free(ss);
  895. return ret;
  896. }
  897. static int gridseed_cp210x_init(struct cgpu_info *gridseed, int interface)
  898. {
  899. // Enable the UART
  900. transfer(gridseed, CP210X_TYPE_OUT, CP210X_REQUEST_IFC_ENABLE, CP210X_VALUE_UART_ENABLE,
  901. interface, C_ENABLE_UART);
  902. if (gridseed->usbinfo.nodev)
  903. return -1;
  904. // Set data control
  905. transfer(gridseed, CP210X_TYPE_OUT, CP210X_REQUEST_DATA, CP210X_VALUE_DATA,
  906. interface, C_SETDATA);
  907. if (gridseed->usbinfo.nodev)
  908. return -1;
  909. // Set the baud
  910. uint32_t data = CP210X_DATA_BAUD;
  911. _transfer(gridseed, CP210X_TYPE_OUT, CP210X_REQUEST_BAUD, 0,
  912. interface, &data, sizeof(data), C_SETBAUD);
  913. return 0;
  914. }
  915. static int gridseed_ftdi_init(struct cgpu_info *gridseed, int interface)
  916. {
  917. int err;
  918. // Reset
  919. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_RESET,
  920. FTDI_VALUE_RESET, interface, C_RESET);
  921. applog(LOG_DEBUG, "%s%i: reset got err %d",
  922. gridseed->drv->name, gridseed->device_id, err);
  923. if (gridseed->usbinfo.nodev)
  924. return -1;
  925. // Set latency
  926. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY,
  927. GRIDSEED_LATENCY, interface, C_LATENCY);
  928. applog(LOG_DEBUG, "%s%i: latency got err %d",
  929. gridseed->drv->name, gridseed->device_id, err);
  930. if (gridseed->usbinfo.nodev)
  931. return -1;
  932. // Set data
  933. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_DATA,
  934. FTDI_VALUE_DATA_AVA, interface, C_SETDATA);
  935. applog(LOG_DEBUG, "%s%i: data got err %d",
  936. gridseed->drv->name, gridseed->device_id, err);
  937. if (gridseed->usbinfo.nodev)
  938. return -1;
  939. // Set the baud
  940. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD_AVA,
  941. (FTDI_INDEX_BAUD_AVA & 0xff00) | interface,
  942. C_SETBAUD);
  943. applog(LOG_DEBUG, "%s%i: setbaud got err %d",
  944. gridseed->drv->name, gridseed->device_id, err);
  945. if (gridseed->usbinfo.nodev)
  946. return -1;
  947. // Set Modem Control
  948. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM,
  949. FTDI_VALUE_MODEM, interface, C_SETMODEM);
  950. applog(LOG_DEBUG, "%s%i: setmodemctrl got err %d",
  951. gridseed->drv->name, gridseed->device_id, err);
  952. if (gridseed->usbinfo.nodev)
  953. return -1;
  954. // Set Flow Control
  955. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW,
  956. FTDI_VALUE_FLOW, interface, C_SETFLOW);
  957. applog(LOG_DEBUG, "%s%i: setflowctrl got err %d",
  958. gridseed->drv->name, gridseed->device_id, err);
  959. if (gridseed->usbinfo.nodev)
  960. return -1;
  961. /* Avalon repeats the following */
  962. // Set Modem Control
  963. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM,
  964. FTDI_VALUE_MODEM, interface, C_SETMODEM);
  965. applog(LOG_DEBUG, "%s%i: setmodemctrl 2 got err %d",
  966. gridseed->drv->name, gridseed->device_id, err);
  967. if (gridseed->usbinfo.nodev)
  968. return -1;
  969. // Set Flow Control
  970. err = usb_transfer(gridseed, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW,
  971. FTDI_VALUE_FLOW, interface, C_SETFLOW);
  972. applog(LOG_DEBUG, "%s%i: setflowctrl 2 got err %d",
  973. gridseed->drv->name, gridseed->device_id, err);
  974. if (gridseed->usbinfo.nodev)
  975. return -1;
  976. return 0;
  977. }
  978. static int gridseed_pl2303_init(struct cgpu_info *gridseed, int interface)
  979. {
  980. // Set Data Control
  981. transfer(gridseed, PL2303_CTRL_OUT, PL2303_REQUEST_CTRL, PL2303_VALUE_CTRL,
  982. interface, C_SETDATA);
  983. if (gridseed->usbinfo.nodev)
  984. return -1;
  985. // Set Line Control
  986. uint32_t ica_data[2] = { PL2303_VALUE_LINE0, PL2303_VALUE_LINE1 };
  987. _transfer(gridseed, PL2303_CTRL_OUT, PL2303_REQUEST_LINE, PL2303_VALUE_LINE,
  988. interface, &ica_data[0], PL2303_VALUE_LINE_SIZE, C_SETLINE);
  989. if (gridseed->usbinfo.nodev)
  990. return -1;
  991. // Vendor
  992. transfer(gridseed, PL2303_VENDOR_OUT, PL2303_REQUEST_VENDOR, PL2303_VALUE_VENDOR,
  993. interface, C_VENDOR);
  994. return 0;
  995. }
  996. static int gridseed_initialise_usb(struct cgpu_info *gridseed, GRIDSEED_INFO *info)
  997. {
  998. int err, interface;
  999. if (gridseed->usbinfo.nodev)
  1000. return -1;
  1001. interface = usb_interface(gridseed);
  1002. info->ident = usb_ident(gridseed);
  1003. switch(info->ident) {
  1004. case IDENT_GSD:
  1005. err = 0;
  1006. break;
  1007. case IDENT_GSD1:
  1008. err = gridseed_cp210x_init(gridseed, interface);
  1009. break;
  1010. case IDENT_GSD2:
  1011. err = gridseed_ftdi_init(gridseed, interface);
  1012. break;
  1013. case IDENT_GSD3:
  1014. err = gridseed_pl2303_init(gridseed, interface);
  1015. break;
  1016. default:
  1017. err = -1;
  1018. applog(LOG_DEBUG, "gridseed_intialise() called with invalid %s cgid %i ident=%d",
  1019. gridseed->drv->name, gridseed->cgminer_id, info->ident);
  1020. }
  1021. return err;
  1022. }
  1023. static struct cgpu_info *gridseed_detect_one_scrypt_proxy()
  1024. {
  1025. struct cgpu_info *gridseed;
  1026. GRIDSEED_INFO *info;
  1027. gridseed = calloc(1, sizeof(struct cgpu_info));
  1028. if (unlikely(!gridseed))
  1029. quit(1, "Failed to calloc struct cgpu_info");
  1030. info = calloc(1, sizeof(GRIDSEED_INFO));
  1031. if (unlikely(!info))
  1032. quit(1, "Failed to calloc struct GRIDSEED_INFO");
  1033. gridseed->drv = &gridseed_drv;
  1034. gridseed->device_data = info;
  1035. gridseed->deven = DEV_ENABLED;
  1036. gridseed->threads = GRIDSEED_MINER_THREADS;
  1037. info->device_fd = -1;
  1038. info->using_libusb = 0;
  1039. info->mode = MODE_SCRYPT_DUAL;
  1040. info->baud = GRIDSEED_DEFAULT_BAUD;
  1041. info->freq = GRIDSEED_DEFAULT_FREQUENCY;
  1042. info->chips = GRIDSEED_DEFAULT_CHIPS;
  1043. info->modules = GRIDSEED_DEFAULT_MODULES;
  1044. info->usefifo = GRIDSEED_DEFAULT_USEFIFO;
  1045. info->btcore = GRIDSEED_DEFAULT_BTCORE;
  1046. info->voltage = 0;
  1047. info->led = 0;
  1048. info->per_chip_stats = 0;
  1049. memset(info->nonce_count, 0, sizeof(info->nonce_count));
  1050. memset(info->error_count, 0, sizeof(info->error_count));
  1051. set_freq_cmd(info, 0, 0, 0);
  1052. info->sockltc = -1;
  1053. info->ltc_port = GRIDSEED_PROXY_PORT;
  1054. cgsem_init(&info->psem);
  1055. get_options(info, opt_gridseed_options);
  1056. if (!gridseed_find_proxy(info))
  1057. goto unallocall;
  1058. if (!add_cgpu(gridseed))
  1059. goto unallocall;
  1060. return gridseed;
  1061. unallocall:
  1062. free(gridseed->device_data);
  1063. gridseed->device_data = NULL;
  1064. free(gridseed);
  1065. return NULL;
  1066. }
  1067. static bool gridseed_detect_one_common(struct cgpu_info *gridseed)
  1068. {
  1069. GRIDSEED_INFO *info = gridseed->device_data;
  1070. unsigned char rbuf[GRIDSEED_READ_SIZE];
  1071. const char detect_cmd[] = "55aac000909090900000000001000000";
  1072. unsigned char detect_data[16];
  1073. if (opt_scrypt)
  1074. info->mode = MODE_SCRYPT;
  1075. else
  1076. info->mode = MODE_SHA256;
  1077. info->baud = GRIDSEED_DEFAULT_BAUD;
  1078. info->freq = GRIDSEED_DEFAULT_FREQUENCY;
  1079. info->chips = GRIDSEED_DEFAULT_CHIPS;
  1080. info->modules = GRIDSEED_DEFAULT_MODULES;
  1081. info->usefifo = GRIDSEED_DEFAULT_USEFIFO;
  1082. info->btcore = GRIDSEED_DEFAULT_BTCORE;
  1083. info->voltage = 0;
  1084. info->led = 0;
  1085. info->per_chip_stats = 0;
  1086. memset(info->nonce_count, 0, sizeof(info->nonce_count));
  1087. memset(info->error_count, 0, sizeof(info->error_count));
  1088. set_freq_cmd(info, 0, 0, 0);
  1089. info->sockltc = -1;
  1090. info->ltc_port = GRIDSEED_PROXY_PORT;
  1091. cgsem_init(&info->psem);
  1092. get_options(info, opt_gridseed_options);
  1093. get_freq(info, opt_gridseed_freq, gridseed->unique_id);
  1094. get_override(info, opt_gridseed_override, gridseed->unique_id);
  1095. /* get MCU firmware version */
  1096. hex2bin(detect_data, detect_cmd, sizeof(detect_data));
  1097. if (gc3355_write(gridseed, detect_data, sizeof(detect_data)) != sizeof(detect_data)) {
  1098. applog(LOG_DEBUG, "Failed to write detect command to gridseed device");
  1099. return false;
  1100. }
  1101. /* waiting for return */
  1102. if (gc3355_get_data(gridseed, rbuf, GRIDSEED_READ_SIZE) != GRIDSEED_READ_SIZE) {
  1103. applog(LOG_DEBUG, "No response from gridseed device");
  1104. return false;
  1105. }
  1106. if (memcmp(rbuf, "\x55\xaa\xc0\x00\x90\x90\x90\x90", GRIDSEED_READ_SIZE-4) != 0) {
  1107. applog(LOG_DEBUG, "Bad response from gridseed device");
  1108. return false;
  1109. }
  1110. if (!add_cgpu(gridseed))
  1111. return false;
  1112. info->fw_version = le32toh(*(uint32_t *)(rbuf+GRIDSEED_READ_SIZE-4));
  1113. applog(LOG_NOTICE, "Gridseed device found, firmware v%08X, driver %s, ID %s",
  1114. info->fw_version, gridseed_version, gridseed->unique_id);
  1115. gc3355_init(gridseed, info);
  1116. return true;
  1117. }
  1118. static struct cgpu_info *gridseed_detect_one_usb(struct libusb_device *dev, struct usb_find_devices *found)
  1119. {
  1120. struct cgpu_info *gridseed;
  1121. GRIDSEED_INFO *info;
  1122. gridseed = usb_alloc_cgpu(&gridseed_drv, GRIDSEED_MINER_THREADS);
  1123. if (!usb_init(gridseed, dev, found))
  1124. goto shin;
  1125. libusb_reset_device(gridseed->usbdev->handle);
  1126. info = calloc(1, sizeof(GRIDSEED_INFO));
  1127. if (unlikely(!info))
  1128. quit(1, "Failed to calloc struct GRIDSEED_INFO");
  1129. update_usb_stats(gridseed);
  1130. gridseed->device_data = info;
  1131. info->device_fd = -1;
  1132. info->using_libusb = 1;
  1133. gridseed->unique_id = gridseed->usbdev->serial_string;
  1134. strncpy(info->id, gridseed->unique_id, sizeof(info->id));
  1135. info->id[sizeof(info->id) - 1] = '\0';
  1136. gridseed->usbdev->usb_type = USB_TYPE_STD;
  1137. if (gridseed_initialise_usb(gridseed, info)) {
  1138. applog(LOG_ERR, "Failed to initialize gridseed device");
  1139. goto unshin;
  1140. }
  1141. if (gridseed_detect_one_common(gridseed))
  1142. return gridseed;
  1143. unshin:
  1144. usb_uninit(gridseed);
  1145. free(gridseed->device_data);
  1146. gridseed->device_data = NULL;
  1147. shin:
  1148. gridseed = usb_free_cgpu(gridseed);
  1149. return NULL;
  1150. }
  1151. static bool gridseed_detect_one_serial(const char *devpath)
  1152. {
  1153. struct cgpu_info *gridseed;
  1154. GRIDSEED_INFO *info;
  1155. int fd;
  1156. if (initial_startup_phase)
  1157. applog(LOG_INFO, "Gridseed Detect: Attempting to open %s", devpath);
  1158. fd = gridseed_serial_open_detect(devpath, GRIDSEED_DEFAULT_BAUD, true);
  1159. if (unlikely(fd == -1)) {
  1160. if (initial_startup_phase)
  1161. applog(LOG_ERR, "Gridseed Detect: Failed to open %s", devpath);
  1162. return false;
  1163. }
  1164. flush_uart(fd);
  1165. gridseed = calloc(1, sizeof(struct cgpu_info));
  1166. if (unlikely(!gridseed))
  1167. quit(1, "Failed to calloc struct cgpu_info");
  1168. info = calloc(1, sizeof(GRIDSEED_INFO));
  1169. if (unlikely(!info))
  1170. quit(1, "Failed to calloc struct GRIDSEED_INFO");
  1171. gridseed->drv = &gridseed_drv;
  1172. gridseed->device_path = strdup(devpath);
  1173. gridseed->device_data = info;
  1174. gridseed->deven = DEV_ENABLED;
  1175. gridseed->threads = GRIDSEED_MINER_THREADS;
  1176. info->device_fd = fd;
  1177. info->using_libusb = 0;
  1178. gridseed->unique_id = MAX( strrchr(gridseed->device_path, '/'),
  1179. strrchr(gridseed->device_path, '\\'));
  1180. if (gridseed->unique_id == NULL)
  1181. gridseed->unique_id = gridseed->device_path;
  1182. else
  1183. ++gridseed->unique_id;
  1184. strncpy(info->id, gridseed->unique_id, sizeof(info->id));
  1185. info->id[sizeof(info->id) - 1] = '\0';
  1186. if (gridseed_detect_one_common(gridseed))
  1187. return true;
  1188. free(gridseed->device_data);
  1189. gridseed->device_data = NULL;
  1190. free(gridseed);
  1191. return false;
  1192. }
  1193. static bool gridseed_send_query_cmd(struct cgpu_info *gridseed, GRIDSEED_INFO *info)
  1194. {
  1195. unsigned char *cmd = (unsigned char *)"\x55\xaa\xc0\x00\xa0\xa0\xa0\xa0\x00\x00\x00\x00\x01\x00\x00\x00";
  1196. cgtimer_t ts_now, ts_res;
  1197. bool ret = false;
  1198. cgtimer_time(&ts_now);
  1199. mutex_lock(&info->qlock);
  1200. if (!info->query_qlen) {
  1201. cgtimer_sub(&ts_now, &info->query_ts, &ts_res);
  1202. #ifndef WIN32
  1203. if (ts_res.tv_sec > 0) {
  1204. #else
  1205. if (ts_res.QuadPart > 10000000) {
  1206. #endif
  1207. if (gc3355_write(gridseed, cmd, 16) == 16) {
  1208. info->query_qlen = true;
  1209. ret = true;
  1210. }
  1211. }
  1212. }
  1213. mutex_unlock(&info->qlock);
  1214. return ret;
  1215. }
  1216. #define SHA256_TASK_LEN 52
  1217. #define SCRYPT_TASK_LEN 156
  1218. static bool gridseed_send_work_usb(struct cgpu_info *gridseed,
  1219. unsigned char *target, unsigned char *midstate, unsigned char *data,
  1220. int workid, enum gsd_mode mode)
  1221. {
  1222. unsigned char cmd[ MAX(SHA256_TASK_LEN, SCRYPT_TASK_LEN) ];
  1223. int ret;
  1224. if (SHA256_MODE(mode)) {
  1225. memcpy(cmd, "\x55\xaa\x0f\x01", 4);
  1226. memcpy(cmd+4, midstate, 32);
  1227. memcpy(cmd+36, data+64, 12);
  1228. memcpy(cmd+48, &(workid), 4);
  1229. } else {
  1230. gc3355_send_cmds(gridseed, str_ltc_reset);
  1231. cgsleep_ms(50);
  1232. memcpy(cmd, "\x55\xaa\x1f\x00", 4);
  1233. memcpy(cmd+4, target, 32);
  1234. memcpy(cmd+36, midstate, 32);
  1235. memcpy(cmd+68, data, 80);
  1236. memcpy(cmd+148, "\xff\xff\xff\xff", 4); // nonce_max
  1237. memcpy(cmd+152, &(workid), 4); // taskid
  1238. }
  1239. ret = gc3355_write(gridseed, cmd, (SHA256_MODE(mode)) ? SHA256_TASK_LEN : SCRYPT_TASK_LEN);
  1240. return (ret == (SHA256_MODE(mode)) ? SHA256_TASK_LEN : SCRYPT_TASK_LEN);
  1241. }
  1242. static bool gridseed_send_work(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  1243. struct work *work)
  1244. {
  1245. if (info->mode == MODE_SCRYPT_DUAL)
  1246. return gridseed_send_work_packet(info, work);
  1247. else
  1248. return gridseed_send_work_usb(gridseed, work->target, work->midstate,
  1249. work->data, work->id, info->mode);
  1250. }
  1251. static void gridseed_get_queue_length(GRIDSEED_INFO *info,
  1252. unsigned char *data)
  1253. {
  1254. uint32_t qlen;
  1255. memcpy(&qlen, data+8, 4);
  1256. qlen = htole32(qlen);
  1257. mutex_lock(&info->qlock);
  1258. info->query_qlen = false;
  1259. info->dev_queue_len = GRIDSEED_MCU_QUEUE_LEN - qlen;
  1260. info->needworks = qlen;
  1261. cgtimer_time(&info->query_ts);
  1262. mutex_unlock(&info->qlock);
  1263. }
  1264. static void gridseed_parse_mcu_command(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  1265. unsigned char *data)
  1266. {
  1267. if (memcmp(data+4, "\xa0\xa0\xa0\xa0", 4) == 0) {
  1268. /* FIFO idle slots */
  1269. gridseed_get_queue_length(info, data);
  1270. } else if (memcmp(data+4, "\x4d\x43\x55\x52\x45\x53\x45\x54", 8) == 0) {
  1271. /* MCU watchdog did HW reset. Re-init GC3355 chips */
  1272. gc3355_init(gridseed, info);
  1273. }
  1274. }
  1275. static void __gridseed_purge_sha_work_queue(struct cgpu_info *gridseed, GRIDSEED_INFO *info, int newstart)
  1276. {
  1277. int i;
  1278. if (newstart <= 0 || newstart >= info->soft_queue_len)
  1279. return;
  1280. for(i=0; i<newstart; i++) {
  1281. work_completed(gridseed, info->workqueue[i]);
  1282. info->workdone++;
  1283. }
  1284. memmove(&(info->workqueue[0]), &(info->workqueue[newstart]),
  1285. sizeof(struct work*)*(info->soft_queue_len - newstart));
  1286. info->soft_queue_len -= newstart;
  1287. }
  1288. static void __maybe_unused gridseed_purge_sha_work_queue(struct cgpu_info *gridseed, GRIDSEED_INFO *info, int newstart)
  1289. {
  1290. mutex_lock(&info->qlock);
  1291. __gridseed_purge_sha_work_queue(gridseed, info, newstart);
  1292. mutex_unlock(&info->qlock);
  1293. }
  1294. static void __gridseed_purge_scrypt_work(GRIDSEED_INFO *info)
  1295. {
  1296. if (info->ltc_work != NULL) {
  1297. free_work(info->ltc_work);
  1298. info->ltc_work = NULL;
  1299. }
  1300. }
  1301. static void gridseed_purge_scrypt_work(GRIDSEED_INFO *info)
  1302. {
  1303. mutex_lock(&info->qlock);
  1304. __gridseed_purge_scrypt_work(info);
  1305. mutex_unlock(&info->qlock);
  1306. }
  1307. static void gridseed_test_btc_nonce(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  1308. struct thr_info *thr, unsigned char *data)
  1309. {
  1310. struct work *work;
  1311. uint32_t nonce, chip;
  1312. unsigned int workid;
  1313. int index, i;
  1314. bool valid = false;
  1315. bool nowork = false;
  1316. memcpy(&workid, data+8, 4);
  1317. memcpy(&nonce, data+4, 4);
  1318. nonce = htole32(nonce);
  1319. chip = nonce / (0xffffffff / info->chips);
  1320. mutex_lock(&info->qlock);
  1321. nowork = (info->soft_queue_len <= 0);
  1322. for(i=0; i<info->soft_queue_len; i++) {
  1323. struct work *dupwork;
  1324. work = info->workqueue[i];
  1325. if (work->devflag == false)
  1326. continue;
  1327. if (work->id > workid)
  1328. break;
  1329. dupwork = copy_work(work);
  1330. if (dupwork == NULL)
  1331. continue;
  1332. if (test_nonce(dupwork, nonce)) {
  1333. submit_tested_work(thr, dupwork);
  1334. index = i;
  1335. valid = true;
  1336. free_work(dupwork);
  1337. break;
  1338. } else
  1339. free_work(dupwork);
  1340. }
  1341. if (valid)
  1342. __gridseed_purge_sha_work_queue(gridseed, info, index);
  1343. info->nonce_count[chip]++;
  1344. if (!valid && !nowork)
  1345. info->error_count[chip]++;
  1346. mutex_unlock(&info->qlock);
  1347. if (!valid && !nowork)
  1348. inc_hw_errors(thr);
  1349. }
  1350. static void __gridseed_test_ltc_nonce(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  1351. struct thr_info *thr, uint32_t nonce, unsigned int workid)
  1352. {
  1353. struct timeval tv_workend;
  1354. uint32_t chip = nonce / (0xffffffff / info->chips);
  1355. bool valid = false;
  1356. cgtime(&tv_workend);
  1357. mutex_lock(&info->qlock);
  1358. if (info->ltc_work == NULL) { /* Work was flushed while the GSD was hashing, *
  1359. * and no new work has been sent yet. */
  1360. applog(LOG_DEBUG, "%s%d sent nonce for flushed work", gridseed->drv->name, gridseed->device_id);
  1361. mutex_unlock(&info->qlock);
  1362. return;
  1363. }
  1364. /*
  1365. if (work->devflag == false) {
  1366. applog(LOG_ERR, "gridseed_test_ltc_nonce called but work hasn't been sent (G:%d L:%d F:%d)", workid, info->last_work_id, info->flushed);
  1367. mutex_unlock(&info->qlock);
  1368. return;
  1369. }
  1370. */
  1371. if (info->ltc_work->id != workid) { /* Work was flushed and new work assigned *
  1372. * just as the GSD reported its result. */
  1373. applog(LOG_DEBUG, "%s%d sent nonce for old work", gridseed->drv->name, gridseed->device_id);
  1374. mutex_unlock(&info->qlock);
  1375. return;
  1376. }
  1377. if (test_nonce(info->ltc_work, nonce)) {
  1378. submit_tested_work(thr, info->ltc_work);
  1379. valid = true;
  1380. }
  1381. info->workdone++;
  1382. info->hashes_per_ms = (nonce % (0xffffffff / info->chips)) * info->chips / ms_tdiff(&tv_workend, &info->ltc_workstart);
  1383. __gridseed_purge_scrypt_work(info);
  1384. info->nonce_count[chip]++;
  1385. if (!valid)
  1386. info->error_count[chip]++;
  1387. mutex_unlock(&info->qlock);
  1388. if (!valid)
  1389. inc_hw_errors(thr);
  1390. }
  1391. static void gridseed_test_ltc_nonce(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  1392. struct thr_info *thr, unsigned char *data)
  1393. {
  1394. uint32_t nonce;
  1395. unsigned int workid;
  1396. memcpy(&workid, data+8, 4);
  1397. memcpy(&nonce, data+4, 4);
  1398. nonce = htole32(nonce);
  1399. __gridseed_test_ltc_nonce(gridseed, info, thr, nonce, workid);
  1400. }
  1401. static void gridseed_parse_response(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
  1402. struct thr_info *thr, unsigned char *readbuf, int *offset)
  1403. {
  1404. unsigned char *p;
  1405. int size;
  1406. p = readbuf;
  1407. size = *offset;
  1408. one_cmd:
  1409. /* search the starting 0x55 */
  1410. while(size > 0) {
  1411. if (likely(*p == 0x55))
  1412. break;
  1413. p++;
  1414. size--;
  1415. }
  1416. if (size < GRIDSEED_READ_SIZE)
  1417. goto out_cmd;
  1418. switch(p[1]) {
  1419. case 0xaa:
  1420. /* Queue length result */
  1421. gridseed_parse_mcu_command(gridseed, info, p);
  1422. break;
  1423. case 0x10:
  1424. /* BTC result */
  1425. gridseed_test_btc_nonce(gridseed, info, thr, p);
  1426. break;
  1427. case 0x20:
  1428. /* LTC result */
  1429. if (SHA256_MODE(info->mode)) {
  1430. gridseed_send_nonce_packet(info, p);
  1431. } else if (SCRYPT_MODE(info->mode)) {
  1432. gridseed_test_ltc_nonce(gridseed, info, thr, p);
  1433. }
  1434. break;
  1435. default:
  1436. applog(LOG_ERR, "%s%d: Received unknown response",
  1437. gridseed->drv->name, gridseed->device_id);
  1438. break;
  1439. }
  1440. p += GRIDSEED_READ_SIZE;
  1441. size -= GRIDSEED_READ_SIZE;
  1442. goto one_cmd;
  1443. out_cmd:
  1444. if (size > 0)
  1445. memmove(readbuf, p, size);
  1446. *offset = size;
  1447. }
  1448. static bool gridseed_check_new_btc_task(GRIDSEED_INFO *info)
  1449. {
  1450. cgtimer_t ts_now, ts_res;
  1451. bool ret = false;
  1452. cgtimer_time(&ts_now);
  1453. mutex_lock(&info->qlock);
  1454. cgtimer_sub(&ts_now, &info->query_ts, &ts_res);
  1455. #ifndef WIN32
  1456. if (ts_res.tv_sec > 0 || ts_res.tv_nsec > 350000000) {
  1457. #else
  1458. if (ts_res.QuadPart > 3500000) {
  1459. #endif
  1460. info->query_qlen = false;
  1461. info->dev_queue_len = 1;
  1462. info->needworks = 1;
  1463. cgtimer_time(&info->query_ts);
  1464. ret = true;
  1465. }
  1466. mutex_unlock(&info->qlock);
  1467. return ret;
  1468. }
  1469. static bool gridseed_check_new_ltc_work(GRIDSEED_INFO *info)
  1470. {
  1471. struct thr_info *thr = info->thr;
  1472. struct work *work;
  1473. const int thr_id = thr->id;
  1474. bool need_work;
  1475. need_work = (info->ltc_work == NULL);
  1476. if (need_work) {
  1477. work = get_work(thr, thr_id);
  1478. mutex_lock(&info->qlock);
  1479. if (info->ltc_work == NULL) {
  1480. work->devflag = false;
  1481. info->ltc_work = work;
  1482. } else {
  1483. need_work = false;
  1484. }
  1485. mutex_unlock(&info->qlock);
  1486. if (!need_work)
  1487. discard_work(work);
  1488. }
  1489. return need_work;
  1490. }
  1491. /*
  1492. * Thread to read response from Miner device
  1493. */
  1494. static void *gridseed_recv_usb(void *userdata)
  1495. {
  1496. struct cgpu_info *gridseed = (struct cgpu_info *)userdata;
  1497. GRIDSEED_INFO *info = gridseed->device_data;
  1498. struct thr_info *thr = info->thr;
  1499. char threadname[24];
  1500. unsigned char readbuf[GRIDSEED_READBUF_SIZE];
  1501. int offset = 0, amount;
  1502. snprintf(threadname, sizeof(threadname), "GridSeed_Recv/%d", gridseed->device_id);
  1503. RenameThread(threadname);
  1504. applog(LOG_INFO, "GridSeed: recv thread running, %s", threadname);
  1505. while (likely(!gridseed->shutdown)) {
  1506. if (unlikely(using_libusb(info) && gridseed->usbinfo.nodev))
  1507. break;
  1508. if (unlikely(info->serial_reopen)) {
  1509. cgsleep_ms(500);
  1510. continue;
  1511. }
  1512. amount = gc3355_read(gridseed, readbuf + offset, GRIDSEED_READ_SIZE, 1);
  1513. if (amount < 0)
  1514. continue;
  1515. offset += amount;
  1516. if (offset >= GRIDSEED_READ_SIZE)
  1517. gridseed_parse_response(gridseed, info, thr, readbuf, &offset);
  1518. if (unlikely(offset + GRIDSEED_READ_SIZE >= GRIDSEED_READBUF_SIZE)) {
  1519. applog(LOG_ERR, "%s%d: Read buffer overflow, resetting", gridseed->drv->name, gridseed->device_id);
  1520. offset = 0;
  1521. }
  1522. }
  1523. gridseed->shutdown = true;
  1524. return NULL;
  1525. }
  1526. /*
  1527. * Thread to send task and queue length query command to device
  1528. */
  1529. static void *gridseed_send(void *userdata)
  1530. {
  1531. struct cgpu_info *gridseed = (struct cgpu_info *)userdata;
  1532. GRIDSEED_INFO *info = gridseed->device_data;
  1533. char threadname[24];
  1534. int i;
  1535. snprintf(threadname, sizeof(threadname), "GridSeed_Send/%d", gridseed->device_id);
  1536. RenameThread(threadname);
  1537. applog(LOG_INFO, "GridSeed: send thread running, %s", threadname);
  1538. while (likely(!gridseed->shutdown)) {
  1539. if (unlikely(using_libusb(info) && gridseed->usbinfo.nodev))
  1540. break;
  1541. if (unlikely(info->serial_reopen)) {
  1542. if (using_serial(info) && !gridseed_reopen(gridseed)) {
  1543. applog(LOG_ERR, "Failed to reopen %s%d on %s, shutting down",
  1544. gridseed->drv->name, gridseed->device_id, gridseed->device_path);
  1545. break;
  1546. }
  1547. info->serial_reopen = false;
  1548. }
  1549. if (SHA256_MODE(info->mode)) {
  1550. cgsleep_ms(50);
  1551. if (info->usefifo == 0) {
  1552. /* mark the first work in queue as complete after several ms */
  1553. if (gridseed_check_new_btc_task(info))
  1554. continue;
  1555. } else {
  1556. /* send query command to device */
  1557. if (gridseed_send_query_cmd(gridseed, info))
  1558. continue;
  1559. }
  1560. /* send task to device */
  1561. mutex_lock(&info->qlock);
  1562. for(i=0; i<info->soft_queue_len; i++) {
  1563. if (info->workqueue[i] && info->workqueue[i]->devflag == false) {
  1564. if (gridseed_send_work(gridseed, info, info->workqueue[i])) {
  1565. info->workqueue[i]->devflag = true;
  1566. break;
  1567. }
  1568. }
  1569. }
  1570. mutex_unlock(&info->qlock);
  1571. } else {
  1572. cgsleep_ms(100);
  1573. if (!gridseed_check_new_ltc_work(info))
  1574. continue;
  1575. /* send task to device */
  1576. mutex_lock(&info->qlock);
  1577. if (info->ltc_work != NULL && !info->ltc_work->devflag &&
  1578. gridseed_send_work(gridseed, info, info->ltc_work)) {
  1579. info->ltc_work->devflag = true;
  1580. cgtime(&info->ltc_workstart);
  1581. }
  1582. mutex_unlock(&info->qlock);
  1583. }
  1584. }
  1585. return NULL;
  1586. }
  1587. /*========== functions for struct device_drv ===========*/
  1588. static int64_t gridseed_scanwork_sha(struct thr_info *);
  1589. static int64_t gridseed_scanwork_scrypt(struct thr_info *);
  1590. static int gridseed_autoscan()
  1591. {
  1592. applog(LOG_DEBUG, "gridseed_autoscan() called");
  1593. return serial_autodetect_udev(gridseed_detect_one_serial, GRIDSEED_USB_ID_MODEL_STR);
  1594. }
  1595. static void gridseed_detect(bool __maybe_unused hotplug)
  1596. {
  1597. static int serial_usb = 0;
  1598. if (initial_startup_phase && hotplug)
  1599. initial_startup_phase = false;
  1600. // -1 : USB , 1 : Serial
  1601. if (serial_usb == 0)
  1602. serial_usb = (list_empty(&scan_devices)) ? -1 : 1;
  1603. if (serial_usb < 0)
  1604. usb_detect(&gridseed_drv, gridseed_detect_one_usb);
  1605. else
  1606. serial_detect_iauto(&gridseed_drv, gridseed_detect_one_serial, gridseed_autoscan);
  1607. if (!total_devices && opt_scrypt)
  1608. while (gridseed_detect_one_scrypt_proxy()) {}
  1609. }
  1610. static bool gridseed_prepare(struct thr_info *thr)
  1611. {
  1612. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1613. struct cgpu_info *gridseed = thr->cgpu;
  1614. GRIDSEED_INFO *info = gridseed->device_data;
  1615. info->thr = thr;
  1616. mutex_init(&info->lock);
  1617. mutex_init(&info->qlock);
  1618. switch (info->mode) {
  1619. case MODE_SHA256:
  1620. case MODE_SHA256_DUAL:
  1621. gridseed_drv.hash_work = hash_queued_work;
  1622. gridseed_drv.scanwork = gridseed_scanwork_sha;
  1623. info->queued = 0;
  1624. info->dev_queue_len = GRIDSEED_MCU_QUEUE_LEN;
  1625. info->soft_queue_len = 0;
  1626. info->needworks = 0;
  1627. info->query_qlen = false;
  1628. cgtimer_time(&info->query_ts);
  1629. memset(&info->workqueue, 0, sizeof(struct work *)*GRIDSEED_SOFT_QUEUE_LEN);
  1630. info->workdone = 0;
  1631. gridseed_create_proxy(gridseed, info);
  1632. break;
  1633. case MODE_SCRYPT:
  1634. case MODE_SCRYPT_DUAL:
  1635. gridseed_drv.hash_work = hash_driver_work;
  1636. gridseed_drv.scanwork = gridseed_scanwork_scrypt;
  1637. info->workdone = 0;
  1638. info->ltc_work = NULL;
  1639. info->hashes_per_ms = GRIDSEED_HASH_SPEED * (double)(info->freq * info->chips * info->modules);
  1640. cgtime(&info->scanhash_time);
  1641. break;
  1642. default:
  1643. applog(LOG_ERR, "Gridseed driver could not determine SHA or Scrypt mode");
  1644. return false;
  1645. }
  1646. if (info->mode == MODE_SCRYPT_DUAL)
  1647. applog(LOG_NOTICE, "Gridseed %s%d opened on %d/UDP",
  1648. gridseed->drv->name, gridseed->device_id, info->ltc_port);
  1649. else
  1650. applog(LOG_NOTICE, "GridSeed %s%d opened on usb:%s",
  1651. gridseed->drv->name, gridseed->device_id, gridseed->device_path);
  1652. return true;
  1653. }
  1654. static bool gridseed_thread_init(struct thr_info *thr)
  1655. {
  1656. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1657. struct cgpu_info *gridseed = thr->cgpu;
  1658. GRIDSEED_INFO *info = gridseed->device_data;
  1659. if (info->mode != MODE_SCRYPT_DUAL) {
  1660. if (pthread_create(&info->th_read, NULL, gridseed_recv_usb, (void*)gridseed)) {
  1661. applog(LOG_ERR, "%s%d: Failed to create read thread", gridseed->drv->name, gridseed->device_id);
  1662. return false;
  1663. }
  1664. }
  1665. if (pthread_create(&info->th_send, NULL, gridseed_send, (void*)gridseed)) {
  1666. applog(LOG_ERR, "%s%d: Failed to create send thread", gridseed->drv->name, gridseed->device_id);
  1667. return false;
  1668. }
  1669. if (info->sockltc != -1) {
  1670. if (pthread_create(&info->th_packet, NULL, gridseed_recv_packet, (void*)gridseed)) {
  1671. applog(LOG_ERR, "%s%d: Failed to create packet thread", gridseed->drv->name, gridseed->device_id);
  1672. return -1;
  1673. }
  1674. }
  1675. return true;
  1676. }
  1677. static bool gridseed_full(struct cgpu_info *gridseed)
  1678. {
  1679. GRIDSEED_INFO *info = gridseed->device_data;
  1680. struct work *work;
  1681. int subid;
  1682. bool ret = true;
  1683. mutex_lock(&info->qlock);
  1684. if (info->needworks <= 0)
  1685. goto out_unlock;
  1686. work = get_queued(gridseed);
  1687. if (unlikely(!work)) {
  1688. ret = false;
  1689. goto out_unlock;
  1690. }
  1691. subid = info->queued++;
  1692. work->subid = subid;
  1693. work->devflag = false; /* true when send to device */
  1694. if (info->soft_queue_len >= GRIDSEED_SOFT_QUEUE_LEN)
  1695. __gridseed_purge_sha_work_queue(gridseed, info, 1);
  1696. info->workqueue[info->soft_queue_len++] = work;
  1697. info->needworks--;
  1698. ret = (info->needworks <= 0);
  1699. out_unlock:
  1700. mutex_unlock(&info->qlock);
  1701. return ret;
  1702. }
  1703. static int64_t gridseed_scanwork_sha(struct thr_info *thr)
  1704. {
  1705. struct cgpu_info *gridseed = thr->cgpu;
  1706. GRIDSEED_INFO *info = gridseed->device_data;
  1707. int64_t hashs;
  1708. cgsleep_ms(100);
  1709. mutex_lock(&info->qlock);
  1710. hashs = info->workdone * 0xffffffffL;
  1711. info->workdone = 0;
  1712. mutex_unlock(&info->qlock);
  1713. return hashs;
  1714. }
  1715. static int64_t gridseed_scanwork_scrypt(struct thr_info *thr)
  1716. {
  1717. struct cgpu_info *gridseed = thr->cgpu;
  1718. GRIDSEED_INFO *info = gridseed->device_data;
  1719. struct timeval old_scanhash_time;
  1720. int64_t elapsed_ms;
  1721. cgsleep_ms(100);
  1722. mutex_lock(&info->qlock);
  1723. old_scanhash_time = info->scanhash_time;
  1724. cgtime(&info->scanhash_time);
  1725. elapsed_ms = ms_tdiff(&info->scanhash_time, &old_scanhash_time);
  1726. mutex_unlock(&info->qlock);
  1727. return info->hashes_per_ms * elapsed_ms;
  1728. }
  1729. #define gridseed_update_work gridseed_flush_work
  1730. static void gridseed_flush_work(struct cgpu_info *gridseed)
  1731. {
  1732. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1733. GRIDSEED_INFO *info = gridseed->device_data;
  1734. applog(LOG_INFO, "%s%d: Work updated, flushing work queue", gridseed->drv->name, gridseed->device_id);
  1735. if (SHA256_MODE(info->mode)) {
  1736. int i;
  1737. mutex_lock(&info->qlock);
  1738. for(i=0; i<info->soft_queue_len; i++) {
  1739. work_completed(gridseed, info->workqueue[i]);
  1740. }
  1741. info->soft_queue_len = 0;
  1742. mutex_unlock(&info->qlock);
  1743. } else {
  1744. gridseed_purge_scrypt_work(info);
  1745. }
  1746. }
  1747. static struct api_data *gridseed_api_stats(struct cgpu_info *gridseed)
  1748. {
  1749. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1750. GRIDSEED_INFO *info = gridseed->device_data;
  1751. struct api_data *root = NULL;
  1752. char *mode_str;
  1753. switch (info->mode) {
  1754. case MODE_SHA256:
  1755. mode_str = MODE_SHA256_STR;
  1756. break;
  1757. case MODE_SHA256_DUAL:
  1758. mode_str = MODE_SHA256_DUAL_STR;
  1759. break;
  1760. case MODE_SCRYPT:
  1761. mode_str = MODE_SCRYPT_STR;
  1762. break;
  1763. case MODE_SCRYPT_DUAL:
  1764. mode_str = MODE_SCRYPT_DUAL_STR;
  1765. break;
  1766. case MODE_UNK:
  1767. default:
  1768. mode_str = MODE_UNK_STR;
  1769. break;
  1770. }
  1771. root = api_add_string(root, "Mode", mode_str, false);
  1772. root = api_add_string(root, "Serial", info->id, false);
  1773. root = api_add_int(root, "Frequency", &(info->freq), false);
  1774. root = api_add_int(root, "Baud", &(info->baud), false);
  1775. root = api_add_int(root, "Chips", &(info->chips), false);
  1776. root = api_add_int(root, "BTCore", &(info->btcore), false);
  1777. root = api_add_int(root, "Modules", &(info->modules), false);
  1778. root = api_add_int(root, "Use FIFO", &(info->usefifo), false);
  1779. root = api_add_int(root, "Voltage", &(info->voltage), false);
  1780. root = api_add_int(root, "Per Chip Stats", &(info->per_chip_stats), false);
  1781. if (SHA256_MODE(info->mode) || info->mode == MODE_SCRYPT_DUAL) {
  1782. root = api_add_short(root, "Scrypt Proxy Port", &info->ltc_port, false);
  1783. }
  1784. root = api_add_timeval(root, "LTC Workstart", &(info->ltc_workstart), false);
  1785. return root;
  1786. }
  1787. static void gridseed_get_statline_before(char *buf, size_t siz, struct cgpu_info *gridseed) {
  1788. GRIDSEED_INFO *info = gridseed->device_data;
  1789. //tailsprintf(buf, siz, "%4d MHz ", info->freq);
  1790. if (info->mode == MODE_SHA256)
  1791. tailsprintf(buf, siz, "SHA256");
  1792. else if (info->mode == MODE_SHA256_DUAL)
  1793. tailsprintf(buf, siz, "DUAL / SHA256");
  1794. else if (info->mode == MODE_SCRYPT)
  1795. tailsprintf(buf, siz, "SCRYPT");
  1796. else if (info->mode == MODE_SCRYPT_DUAL)
  1797. tailsprintf(buf, siz, "DUAL / SCRYPT");
  1798. tailsprintf(buf, siz, " %4d MHz ", info->freq); //fix typo
  1799. }
  1800. static void gridseed_get_statline(char *buf, size_t siz, struct cgpu_info *gridseed) {
  1801. GRIDSEED_INFO *info = gridseed->device_data;
  1802. /* With the per_chip_stats option, print the number of nonces
  1803. * and (if applicable) HW errors per chip at the end of each
  1804. * device's status line. This however only works for small numbers
  1805. * of chips, otherwise the information extends off screen and
  1806. * the string buffer could overflow */
  1807. if (info->per_chip_stats && info->chips <= GRIDSEED_DEFAULT_CHIPS * 2) {
  1808. int i;
  1809. tailsprintf(buf, siz, " N:");
  1810. for (i = 0; i < info->chips; ++i) {
  1811. tailsprintf(buf, siz, " %d", info->nonce_count[i]);
  1812. if (info->error_count[i])
  1813. tailsprintf(buf, siz, "[%d]", info->error_count[i]);
  1814. }
  1815. }
  1816. }
  1817. static char *gridseed_set_device(struct cgpu_info *gridseed, char *option, char *setting, char *replybuf)
  1818. {
  1819. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1820. GRIDSEED_INFO *info = gridseed->device_data;
  1821. int val;
  1822. if (strcasecmp(option, "help") == 0) {
  1823. sprintf(replybuf, "freq: range %d-%d",
  1824. GRIDSEED_MIN_FREQUENCY, GRIDSEED_MAX_FREQUENCY);
  1825. return replybuf;
  1826. }
  1827. if (strcasecmp(option, "freq") == 0) {
  1828. if (!setting || !*setting) {
  1829. sprintf(replybuf, "missing freq setting");
  1830. return replybuf;
  1831. }
  1832. val = atoi(setting);
  1833. if (val < GRIDSEED_MIN_FREQUENCY || val > GRIDSEED_MAX_FREQUENCY) {
  1834. sprintf(replybuf, "invalid freq: '%s' valid range %d-%d",
  1835. setting, GRIDSEED_MIN_FREQUENCY, GRIDSEED_MAX_FREQUENCY);
  1836. return replybuf;
  1837. }
  1838. info->freq = val;
  1839. set_freq_cmd(info, 0, 0, 0);
  1840. gc3355_set_core_freq(gridseed);
  1841. return NULL;
  1842. }
  1843. sprintf(replybuf, "Unknown option: %s", option);
  1844. return replybuf;
  1845. }
  1846. static void gridseed_reinit(struct cgpu_info __maybe_unused *gridseed)
  1847. {
  1848. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1849. }
  1850. static void gridseed_shutdown(struct thr_info *thr)
  1851. {
  1852. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1853. struct cgpu_info *gridseed = thr->cgpu;
  1854. GRIDSEED_INFO *info = gridseed->device_data;
  1855. applog(LOG_NOTICE, "%s%d: Shutting down", gridseed->drv->name, gridseed->device_id);
  1856. pthread_join(info->th_packet, NULL);
  1857. pthread_join(info->th_send, NULL);
  1858. if (info->mode != MODE_SCRYPT_DUAL)
  1859. pthread_join(info->th_read, NULL);
  1860. cgsem_destroy(&info->psem);
  1861. mutex_destroy(&info->qlock);
  1862. mutex_destroy(&info->lock);
  1863. if (info->sockltc != -1) {
  1864. sockclose(info->sockltc);
  1865. info->sockltc = -1;
  1866. }
  1867. if (info->mode != MODE_SCRYPT_DUAL)
  1868. gc3355_send_cmds(gridseed, str_reset);
  1869. }
  1870. static void gridseed_hw_errors(struct thr_info __maybe_unused *thr)
  1871. {
  1872. applog(LOG_DEBUG, "Entering %s", __FUNCTION__);
  1873. #if 0
  1874. struct cgpu_info *gridseed = thr->cgpu;
  1875. GRIDSEED_INFO *info = gridseed->device_data;
  1876. if (gridseed->hw_errors > 5) {
  1877. gc3355_init(gridseed, info, true);
  1878. gridseed->hw_errors = 0;
  1879. applog(LOG_ERR, "HW error, do hardware reset");
  1880. }
  1881. #endif
  1882. }
  1883. /* driver functions */
  1884. struct device_drv gridseed_drv = {
  1885. .drv_id = DRIVER_gridseed,
  1886. .dname = "gridseed",
  1887. .name = "GSD",
  1888. .drv_detect = gridseed_detect,
  1889. .thread_prepare = gridseed_prepare, // called before miner thread is created
  1890. .thread_init = gridseed_thread_init, // called at start of miner thread
  1891. //.thread_enable = gridseed_thread_enable,
  1892. //.hash_work // set in gridseed_prepare // called in miner thread, main loop
  1893. .queue_full = gridseed_full, // sha256 only // called to determine if driver needs more work; applies only if hash_work = hash_queued_work
  1894. //.scanwork // set in gridseed_prepare // called repeatedly from the loop in hash_work
  1895. .flush_work = gridseed_flush_work, // called when new block detected on network */
  1896. .update_work = gridseed_update_work,
  1897. .get_api_stats = gridseed_api_stats,
  1898. .get_statline_before = gridseed_get_statline_before,
  1899. .get_statline = gridseed_get_statline,
  1900. .set_device = gridseed_set_device,
  1901. .reinit_device = gridseed_reinit, // used by watchdog to restart hung drivers
  1902. .thread_shutdown = gridseed_shutdown, // called last thing in miner thread, after hash_work has returned
  1903. .hw_error = gridseed_hw_errors, // called from submit_nonce or inc_hw_errors
  1904. };