cgminer/patches/0001-add-icarus.c-base-on-bitforce.c.patch |
1 | | From 340b923e42d32bd5173fe6b285923635a6fcc67f Mon Sep 17 00:00:00 2001 |
2 | | From: Xiangfu <xiangfu@openmobilefree.net> |
3 | | Date: Mon, 13 Feb 2012 16:04:34 +0800 |
4 | | Subject: [PATCH 1/7] add icarus.c, base on bitforce.c |
5 | | |
6 | | icarus.c | 307 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
7 | | 1 files changed, 307 insertions(+), 0 deletions(-) |
8 | | create mode 100644 icarus.c |
9 | | |
10 | | diff --git a/icarus.c b/icarus.c |
11 | | new file mode 100644 |
12 | | index 0000000..56b8d8a |
13 | | +++ b/icarus.c |
14 | | @@ -0,0 +1,307 @@ |
15 | | +/* |
16 | | + * Copyright 2012 Luke Dashjr |
17 | | + * Copyright 2012 Xiangfu <xiangfu@openmobilefree.com> |
18 | | + * |
19 | | + * This program is free software; you can redistribute it and/or modify it |
20 | | + * under the terms of the GNU General Public License as published by the Free |
21 | | + * Software Foundation; either version 2 of the License, or (at your option) |
22 | | + * any later version. See COPYING for more details. |
23 | | + */ |
24 | | + |
25 | | +/* |
26 | | + * Those code should be works fine with V2 and V3 bitstream of Icarus. |
27 | | + * Operation: |
28 | | + * No detection implement. |
29 | | + * Input: 64B = 32B midstate + 20B fill bytes + last 12 bytes of block head. |
30 | | + * Return: send back 32bits immediately when Icarus found a valid nonce. |
31 | | + * no query protocol implemented here, if no data send back in ~11.3 |
32 | | + * seconds (full cover time on 32bit nonce range by 380MH/s speed) |
33 | | + * just send another work. |
34 | | + * Notice: |
35 | | + * 1. Icarus will start calculate when you push a work to them, even they |
36 | | + * are busy. |
37 | | + * 2. The 2 FPGAs on Icarus will distribute the job, one will calculate the |
38 | | + * 0 ~ 7FFFFFFF, another one will cover the 80000000 ~ FFFFFFFF. |
39 | | + * 3. It's possible for 2 FPGAs both find valid nonce in the meantime, the 2 |
40 | | + * valid nonce will all be send back. |
41 | | + * 4. Icarus will stop work when: a valid nonce has been found or 32 bits |
42 | | + * nonce range is completely calculated. |
43 | | + */ |
44 | | + |
45 | | +#include <limits.h> |
46 | | +#include <pthread.h> |
47 | | +#include <stdio.h> |
48 | | +#include <sys/time.h> |
49 | | +#include <sys/types.h> |
50 | | +#include <dirent.h> |
51 | | +#include <unistd.h> |
52 | | +#ifndef WIN32 |
53 | | + #include <termios.h> |
54 | | + #include <sys/stat.h> |
55 | | + #include <fcntl.h> |
56 | | + #ifndef O_CLOEXEC |
57 | | + #define O_CLOEXEC 0 |
58 | | + #endif |
59 | | +#else |
60 | | + #include <windows.h> |
61 | | + #include <io.h> |
62 | | +#endif |
63 | | + |
64 | | +#include "elist.h" |
65 | | +#include "miner.h" |
66 | | + |
67 | | +#define ICARUS_READ_FAULT_COUNT (8) |
68 | | + |
69 | | +int icarus_read_count; |
70 | | +struct device_api icarus_api; |
71 | | + |
72 | | +static void rev(unsigned char *s, size_t l) |
73 | | +{ |
74 | | + size_t i, j; |
75 | | + unsigned char t; |
76 | | + |
77 | | + for (i = 0, j = l - 1; i < j; i++, j--) { |
78 | | + t = s[i]; |
79 | | + s[i] = s[j]; |
80 | | + s[j] = t; |
81 | | + } |
82 | | +} |
83 | | + |
84 | | +static int icarus_open(const char *devpath) |
85 | | +{ |
86 | | +#ifndef WIN32 |
87 | | + struct termios my_termios; |
88 | | + |
89 | | + int serialfd = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY); |
90 | | + |
91 | | + if (serialfd == -1) |
92 | | + return -1; |
93 | | + |
94 | | + tcgetattr(serialfd, &my_termios); |
95 | | + my_termios.c_cflag = B115200; |
96 | | + my_termios.c_cflag |= CS8; |
97 | | + my_termios.c_cflag |= CREAD; |
98 | | + my_termios.c_cflag |= CLOCAL; |
99 | | + my_termios.c_cflag &= ~(CSIZE | PARENB); |
100 | | + |
101 | | + my_termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | |
102 | | + ISTRIP | INLCR | IGNCR | ICRNL | IXON); |
103 | | + my_termios.c_oflag &= ~OPOST; |
104 | | + my_termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); |
105 | | + my_termios.c_cc[VTIME] = 10; /* block 1 second */ |
106 | | + my_termios.c_cc[VMIN] = 0; |
107 | | + tcsetattr(serialfd, TCSANOW, &my_termios); |
108 | | + |
109 | | + tcflush(serialfd, TCOFLUSH); |
110 | | + tcflush(serialfd, TCIFLUSH); |
111 | | + |
112 | | + return serialfd; |
113 | | +#else |
114 | | + HANDLE hSerial = CreateFile(devpath, GENERIC_READ | GENERIC_WRITE, 0, |
115 | | + NULL, OPEN_EXISTING, 0, NULL); |
116 | | + if (unlikely(hSerial == INVALID_HANDLE_VALUE)) |
117 | | + return -1; |
118 | | + /* TODO: Needs setup read block time. just like VTIME = 10 */ |
119 | | + return _open_osfhandle((LONG)hSerial, 0); |
120 | | +#endif |
121 | | +} |
122 | | + |
123 | | +static void icarus_gets(char *buf, size_t bufLen, int fd) |
124 | | +{ |
125 | | + ssize_t ret = 0; |
126 | | + |
127 | | + icarus_read_count = 0; |
128 | | + |
129 | | + while (bufLen) { |
130 | | + ret = read(fd, buf, 1); |
131 | | + if (ret == 1) { |
132 | | + bufLen--; |
133 | | + buf++; |
134 | | + continue; |
135 | | + } |
136 | | + |
137 | | + icarus_read_count++; |
138 | | + if (icarus_read_count == ICARUS_READ_FAULT_COUNT) { |
139 | | + applog(LOG_WARNING, |
140 | | + "Icarus Read: No data in %d seconds", |
141 | | + ICARUS_READ_FAULT_COUNT); |
142 | | + break; |
143 | | + } |
144 | | + } |
145 | | +} |
146 | | + |
147 | | +static void icarus_write(int fd, const void *buf, size_t bufLen) |
148 | | +{ |
149 | | + ssize_t ret; |
150 | | + |
151 | | + ret = write(fd, buf, bufLen); |
152 | | + if (unlikely(ret != bufLen)) |
153 | | + quit(1, "Icarus: Send data failed!"); |
154 | | +} |
155 | | + |
156 | | +#define icarus_close(fd) close(fd) |
157 | | + |
158 | | +static bool icarus_detect_one(const char *devpath) |
159 | | +{ |
160 | | + int fd; |
161 | | + static int i = 0; |
162 | | + |
163 | | + const unsigned char golden_ob[] = |
164 | | + "2db907f9cb4eb938ded904f4832c4331" |
165 | | + "0380e3aeb54364057e7fec5157bfc533" |
166 | | + "00000000000000000000000080000000" |
167 | | + "00000000a58e091ac342724e7c3dc346"; |
168 | | + const unsigned char golden_nonce[] = "063c5e01"; |
169 | | + |
170 | | + char ob_bin[64], nonce_bin[4]; |
171 | | + char *nonce_hex; |
172 | | + |
173 | | + if (total_devices == MAX_DEVICES) |
174 | | + return false; |
175 | | + |
176 | | + fd = icarus_open(devpath); |
177 | | + if (unlikely(fd == -1)) { |
178 | | + applog(LOG_ERR, "Icarus Detect: Failed to open %s", devpath); |
179 | | + return false; |
180 | | + } |
181 | | + |
182 | | + hex2bin(ob_bin, golden_ob, sizeof(ob_bin)); |
183 | | + icarus_write(fd, ob_bin, sizeof(ob_bin)); |
184 | | + |
185 | | + memset(nonce_bin, 0, sizeof(nonce_bin)); |
186 | | + icarus_gets(nonce_bin, sizeof(nonce_bin), fd); |
187 | | + |
188 | | + icarus_close(fd); |
189 | | + |
190 | | + nonce_hex = bin2hex(nonce_bin, sizeof(nonce_bin)); |
191 | | + if (nonce_hex) { |
192 | | + if (strncmp(nonce_hex, golden_nonce, 8)) { |
193 | | + applog(LOG_ERR, |
194 | | + "Icarus Detect: " |
195 | | + "Test failed at %s : get %s, should: %s", |
196 | | + devpath, nonce_hex, golden_nonce); |
197 | | + free(nonce_hex); |
198 | | + return false; |
199 | | + } |
200 | | + free(nonce_hex); |
201 | | + } else |
202 | | + return false; |
203 | | + |
204 | | + /* We have a real Icarus! */ |
205 | | + struct cgpu_info *icarus; |
206 | | + icarus = calloc(1, sizeof(*icarus)); |
207 | | + devices[total_devices++] = icarus; |
208 | | + icarus->api = &icarus_api; |
209 | | + icarus->device_id = i++; |
210 | | + icarus->device_path = strdup(devpath); |
211 | | + icarus->threads = 1; |
212 | | + |
213 | | + return true; |
214 | | +} |
215 | | + |
216 | | +static void icarus_detect() |
217 | | +{ |
218 | | + struct string_elist *iter, *tmp; |
219 | | + |
220 | | + list_for_each_entry_safe(iter, tmp, &scan_devices, list) { |
221 | | + if (icarus_detect_one(iter->string)) |
222 | | + string_elist_del(iter); |
223 | | + } |
224 | | +} |
225 | | + |
226 | | +static bool icarus_thread_prepare(struct thr_info *thr) |
227 | | +{ |
228 | | + struct cgpu_info *icarus = thr->cgpu; |
229 | | + |
230 | | + struct timeval now; |
231 | | + |
232 | | + int fd = icarus_open(icarus->device_path); |
233 | | + if (unlikely(-1 == fd)) { |
234 | | + applog(LOG_ERR, "Failed to open Icarus on %s", |
235 | | + icarus->device_path); |
236 | | + return false; |
237 | | + } |
238 | | + |
239 | | + icarus->device_fd = fd; |
240 | | + |
241 | | + applog(LOG_INFO, "Opened Icarus on %s", icarus->device_path); |
242 | | + gettimeofday(&now, NULL); |
243 | | + get_datestamp(icarus->init, &now); |
244 | | + |
245 | | + return true; |
246 | | +} |
247 | | + |
248 | | +static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, |
249 | | + uint64_t max_nonce) |
250 | | +{ |
251 | | + struct cgpu_info *icarus; |
252 | | + int fd; |
253 | | + |
254 | | + unsigned char ob_bin[64], nonce_bin[4]; |
255 | | + unsigned char *ob_hex, *nonce_hex; |
256 | | + uint32_t nonce; |
257 | | + uint32_t hash_count; |
258 | | + time_t t; |
259 | | + |
260 | | + icarus = thr->cgpu; |
261 | | + fd = icarus->device_fd; |
262 | | + |
263 | | + memset(ob_bin, 0, sizeof(ob_bin)); |
264 | | + memcpy(ob_bin, work->midstate, 32); |
265 | | + memcpy(ob_bin + 52, work->data + 64, 12); |
266 | | + rev(ob_bin, 32); |
267 | | + rev(ob_bin + 52, 12); |
268 | | +#ifndef WIN32 |
269 | | + tcflush(fd, TCOFLUSH); |
270 | | +#endif |
271 | | + icarus_write(fd, ob_bin, sizeof(ob_bin)); |
272 | | + |
273 | | + ob_hex = bin2hex(ob_bin, sizeof(ob_bin)); |
274 | | + if (ob_hex) { |
275 | | + t = time(NULL); |
276 | | + applog(LOG_DEBUG, "Icarus send : %s", ob_hex); |
277 | | + free(ob_hex); |
278 | | + } |
279 | | + |
280 | | + /* Icarus will return 8 bytes nonces or nothing */ |
281 | | + memset(nonce_bin, 0, sizeof(nonce_bin)); |
282 | | + icarus_gets(nonce_bin, sizeof(nonce_bin), fd); |
283 | | + |
284 | | + nonce_hex = bin2hex(nonce_bin, sizeof(nonce_bin)); |
285 | | + if (nonce_hex) { |
286 | | + t = time(NULL) - t; |
287 | | + applog(LOG_DEBUG, "Icarus return (elapse %d seconds): %s", |
288 | | + t, nonce_hex); |
289 | | + free(nonce_hex); |
290 | | + } |
291 | | + |
292 | | + memcpy((char *)&nonce, nonce_bin, sizeof(nonce_bin)); |
293 | | + |
294 | | + if (nonce == 0 && icarus_read_count == ICARUS_READ_FAULT_COUNT) |
295 | | + return 0xffffffff; |
296 | | + |
297 | | +#ifndef __BIG_ENDIAN__ |
298 | | + nonce = swab32(nonce); |
299 | | +#endif |
300 | | + work->blk.nonce = 0xffffffff; |
301 | | + submit_nonce(thr, work, nonce); |
302 | | + |
303 | | + hash_count = (nonce & 0x7fffffff); |
304 | | + if (hash_count == 0) |
305 | | + hash_count = 2; |
306 | | + else { |
307 | | + if (hash_count++ == 0x7fffffff) |
308 | | + hash_count = 0xffffffff; |
309 | | + else |
310 | | + hash_count <<= 1; |
311 | | + } |
312 | | + |
313 | | + return hash_count; |
314 | | +} |
315 | | + |
316 | | +struct device_api icarus_api = { |
317 | | + .name = "Icarus", |
318 | | + .api_detect = icarus_detect, |
319 | | + .thread_prepare = icarus_thread_prepare, |
320 | | + .scanhash = icarus_scanhash, |
321 | | +}; |
322 | | 1.7.5.4 |
323 | | |
cgminer/patches/0001-fix-the-name-to-3-chars-fix-the-multi-icarus-support.patch |
| 1 | From 88fae1c0217e68d43480c73d78efdcc2665c5f13 Mon Sep 17 00:00:00 2001 |
| 2 | From: Xiangfu <xiangfu@openmobilefree.net> |
| 3 | Date: Sat, 25 Feb 2012 22:09:47 +0800 |
| 4 | Subject: [PATCH 1/2] fix the name to 3 chars, fix the multi-icarus support |
| 5 | |
| 6 | --- |
| 7 | icarus.c | 48 +++++++++++++++++++++++++----------------------- |
| 8 | 1 files changed, 25 insertions(+), 23 deletions(-) |
| 9 | |
| 10 | diff --git a/icarus.c b/icarus.c |
| 11 | index 7739395..1d59657 100644 |
| 12 | --- a/icarus.c |
| 13 | @@ -52,9 +52,6 @@ |
| 14 | |
| 15 | #define ICARUS_READ_FAULT_COUNT (8) |
| 16 | |
| 17 | -static int icarus_read_count; |
| 18 | -static int icarus_write_fault; |
| 19 | - |
| 20 | struct device_api icarus_api; |
| 21 | |
| 22 | static void rev(unsigned char *s, size_t l) |
| 23 | @@ -108,11 +105,10 @@ static int icarus_open(const char *devpath) |
| 24 | #endif |
| 25 | } |
| 26 | |
| 27 | -static void icarus_gets(unsigned char *buf, size_t bufLen, int fd) |
| 28 | +static int icarus_gets(unsigned char *buf, size_t bufLen, int fd) |
| 29 | { |
| 30 | ssize_t ret = 0; |
| 31 | - |
| 32 | - icarus_read_count = 0; |
| 33 | + int rc = 0; |
| 34 | |
| 35 | while (bufLen) { |
| 36 | ret = read(fd, buf, 1); |
| 37 | @@ -122,23 +118,26 @@ static void icarus_gets(unsigned char *buf, size_t bufLen, int fd) |
| 38 | continue; |
| 39 | } |
| 40 | |
| 41 | - icarus_read_count++; |
| 42 | - if (icarus_read_count == ICARUS_READ_FAULT_COUNT) { |
| 43 | + rc++; |
| 44 | + if (rc == ICARUS_READ_FAULT_COUNT) { |
| 45 | applog(LOG_WARNING, |
| 46 | - "Icarus Read: No data in %d seconds", |
| 47 | - ICARUS_READ_FAULT_COUNT); |
| 48 | - break; |
| 49 | + "Icarus Read: No data in %d seconds", rc); |
| 50 | + return 1; |
| 51 | } |
| 52 | } |
| 53 | + |
| 54 | + return 0; |
| 55 | } |
| 56 | |
| 57 | -static void icarus_write(int fd, const void *buf, size_t bufLen) |
| 58 | +static int icarus_write(int fd, const void *buf, size_t bufLen) |
| 59 | { |
| 60 | size_t ret; |
| 61 | |
| 62 | ret = write(fd, buf, bufLen); |
| 63 | if (unlikely(ret != bufLen)) |
| 64 | - icarus_write_fault = 1; |
| 65 | + return 1; |
| 66 | + |
| 67 | + return 0; |
| 68 | } |
| 69 | |
| 70 | #define icarus_close(fd) close(fd) |
| 71 | @@ -179,7 +178,7 @@ static bool icarus_detect_one(const char *devpath) |
| 72 | if (strncmp(nonce_hex, golden_nonce, 8)) { |
| 73 | applog(LOG_ERR, |
| 74 | "Icarus Detect: " |
| 75 | - "Test failed at %s : get %s, should: %s", |
| 76 | + "Test failed at %s: get %s, should: %s", |
| 77 | devpath, nonce_hex, golden_nonce); |
| 78 | free(nonce_hex); |
| 79 | return false; |
| 80 | @@ -197,7 +196,8 @@ static bool icarus_detect_one(const char *devpath) |
| 81 | icarus->threads = 1; |
| 82 | devices[total_devices++] = icarus; |
| 83 | |
| 84 | - icarus_write_fault = 0; |
| 85 | + applog(LOG_INFO, "Found Icarus at %s, mark as %d", |
| 86 | + devpath, icarus->device_id); |
| 87 | |
| 88 | return true; |
| 89 | } |
| 90 | @@ -239,6 +239,7 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, |
| 91 | { |
| 92 | struct cgpu_info *icarus; |
| 93 | int fd; |
| 94 | + int ret; |
| 95 | |
| 96 | unsigned char ob_bin[64], nonce_bin[4]; |
| 97 | char *ob_hex, *nonce_hex; |
| 98 | @@ -257,32 +258,33 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, |
| 99 | #ifndef WIN32 |
| 100 | tcflush(fd, TCOFLUSH); |
| 101 | #endif |
| 102 | - icarus_write(fd, ob_bin, sizeof(ob_bin)); |
| 103 | - if (icarus_write_fault) |
| 104 | + ret = icarus_write(fd, ob_bin, sizeof(ob_bin)); |
| 105 | + if (ret) |
| 106 | return 0; /* This should never happen */ |
| 107 | |
| 108 | ob_hex = bin2hex(ob_bin, sizeof(ob_bin)); |
| 109 | if (ob_hex) { |
| 110 | t = time(NULL); |
| 111 | - applog(LOG_DEBUG, "Icarus send : %s", ob_hex); |
| 112 | + applog(LOG_DEBUG, "Icarus %s send: %s", |
| 113 | + icarus->device_id, ob_hex); |
| 114 | free(ob_hex); |
| 115 | } |
| 116 | |
| 117 | /* Icarus will return 8 bytes nonces or nothing */ |
| 118 | memset(nonce_bin, 0, sizeof(nonce_bin)); |
| 119 | - icarus_gets(nonce_bin, sizeof(nonce_bin), fd); |
| 120 | + ret = icarus_gets(nonce_bin, sizeof(nonce_bin), fd); |
| 121 | |
| 122 | nonce_hex = bin2hex(nonce_bin, sizeof(nonce_bin)); |
| 123 | if (nonce_hex) { |
| 124 | t = time(NULL) - t; |
| 125 | - applog(LOG_DEBUG, "Icarus return (elapse %d seconds): %s", |
| 126 | - t, nonce_hex); |
| 127 | + applog(LOG_DEBUG, "Icarus %d return (elapse %d seconds): %s", |
| 128 | + icarus->device_id, t, nonce_hex); |
| 129 | free(nonce_hex); |
| 130 | } |
| 131 | |
| 132 | memcpy((char *)&nonce, nonce_bin, sizeof(nonce_bin)); |
| 133 | |
| 134 | - if (nonce == 0 && icarus_read_count == ICARUS_READ_FAULT_COUNT) |
| 135 | + if (nonce == 0 && ret) |
| 136 | return 0xffffffff; |
| 137 | |
| 138 | #ifndef __BIG_ENDIAN__ |
| 139 | @@ -324,7 +326,7 @@ static void icarus_shutdown(struct thr_info *thr) |
| 140 | } |
| 141 | |
| 142 | struct device_api icarus_api = { |
| 143 | - .name = "Icarus", |
| 144 | + .name = "ICA", |
| 145 | .api_detect = icarus_detect, |
| 146 | .thread_prepare = icarus_prepare, |
| 147 | .scanhash = icarus_scanhash, |
| 148 | -- |
| 149 | 1.7.5.4 |
| 150 | |
cgminer/patches/0002-add-shutdown-function.patch |
1 | | From 706c4de11159e06284b70cc1d12ba9c2cbcbb684 Mon Sep 17 00:00:00 2001 |
2 | | From: Xiangfu <xiangfu@openmobilefree.net> |
3 | | Date: Sun, 19 Feb 2012 21:31:58 +0800 |
4 | | Subject: [PATCH 2/7] add shutdown function |
5 | | |
6 | | icarus.c | 42 ++++++++++++++++++++++++++++++++++-------- |
7 | | 1 files changed, 34 insertions(+), 8 deletions(-) |
8 | | |
9 | | diff --git a/icarus.c b/icarus.c |
10 | | index 56b8d8a..5562e5e 100644 |
11 | | +++ b/icarus.c |
12 | | @@ -52,7 +52,9 @@ |
13 | | |
14 | | #define ICARUS_READ_FAULT_COUNT (8) |
15 | | |
16 | | -int icarus_read_count; |
17 | | +static int icarus_read_count; |
18 | | +static int icarus_write_fault; |
19 | | + |
20 | | struct device_api icarus_api; |
21 | | |
22 | | static void rev(unsigned char *s, size_t l) |
23 | | @@ -136,7 +138,7 @@ static void icarus_write(int fd, const void *buf, size_t bufLen) |
24 | | |
25 | | ret = write(fd, buf, bufLen); |
26 | | if (unlikely(ret != bufLen)) |
27 | | - quit(1, "Icarus: Send data failed!"); |
28 | | + icarus_write_fault = 1; |
29 | | } |
30 | | |
31 | | #define icarus_close(fd) close(fd) |
32 | | @@ -144,7 +146,6 @@ static void icarus_write(int fd, const void *buf, size_t bufLen) |
33 | | static bool icarus_detect_one(const char *devpath) |
34 | | { |
35 | | int fd; |
36 | | - static int i = 0; |
37 | | |
38 | | const unsigned char golden_ob[] = |
39 | | "2db907f9cb4eb938ded904f4832c4331" |
40 | | @@ -189,12 +190,14 @@ static bool icarus_detect_one(const char *devpath) |
41 | | |
42 | | /* We have a real Icarus! */ |
43 | | struct cgpu_info *icarus; |
44 | | - icarus = calloc(1, sizeof(*icarus)); |
45 | | - devices[total_devices++] = icarus; |
46 | | + icarus = calloc(1, sizeof(struct cgpu_info)); |
47 | | icarus->api = &icarus_api; |
48 | | - icarus->device_id = i++; |
49 | | + icarus->device_id = total_devices; |
50 | | icarus->device_path = strdup(devpath); |
51 | | icarus->threads = 1; |
52 | | + devices[total_devices++] = icarus; |
53 | | + |
54 | | + icarus_write_fault = 0; |
55 | | |
56 | | return true; |
57 | | } |
58 | | @@ -209,7 +212,7 @@ static void icarus_detect() |
59 | | } |
60 | | } |
61 | | |
62 | | -static bool icarus_thread_prepare(struct thr_info *thr) |
63 | | +static bool icarus_prepare(struct thr_info *thr) |
64 | | { |
65 | | struct cgpu_info *icarus = thr->cgpu; |
66 | | |
67 | | @@ -255,6 +258,8 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, |
68 | | tcflush(fd, TCOFLUSH); |
69 | | #endif |
70 | | icarus_write(fd, ob_bin, sizeof(ob_bin)); |
71 | | + if (icarus_write_fault) |
72 | | + return 0; /* This should never happen */ |
73 | | |
74 | | ob_hex = bin2hex(ob_bin, sizeof(ob_bin)); |
75 | | if (ob_hex) { |
76 | | @@ -299,9 +304,30 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, |
77 | | return hash_count; |
78 | | } |
79 | | |
80 | | +static void icarus_shutdown(struct thr_info *thr) |
81 | | +{ |
82 | | + struct cgpu_info *icarus; |
83 | | + int fd; |
84 | | + |
85 | | + if (thr->cgpu) { |
86 | | + icarus = thr->cgpu; |
87 | | + |
88 | | + if (icarus->device_path) |
89 | | + free(icarus->device_path); |
90 | | + |
91 | | + close(icarus->device_fd); |
92 | | + |
93 | | + devices[icarus->device_id] = NULL; |
94 | | + free(icarus); |
95 | | + |
96 | | + thr->cgpu = NULL; |
97 | | + } |
98 | | +} |
99 | | + |
100 | | struct device_api icarus_api = { |
101 | | .name = "Icarus", |
102 | | .api_detect = icarus_detect, |
103 | | - .thread_prepare = icarus_thread_prepare, |
104 | | + .thread_prepare = icarus_prepare, |
105 | | .scanhash = icarus_scanhash, |
106 | | + .thread_shutdown = icarus_shutdown, |
107 | | }; |
108 | | 1.7.5.4 |
109 | | |
cgminer/patches/0003-add-icarus-to-cgminer.c.patch |
1 | | From f46c2b28a0d50a026354013ead0963ce4248ef4e Mon Sep 17 00:00:00 2001 |
2 | | From: Xiangfu <xiangfu@openmobilefree.net> |
3 | | Date: Mon, 13 Feb 2012 16:09:45 +0800 |
4 | | Subject: [PATCH 3/7] add icarus to cgminer.c |
5 | | |
6 | | cgminer.c | 19 +++++++++++++++---- |
7 | | 1 files changed, 15 insertions(+), 4 deletions(-) |
8 | | |
9 | | diff --git a/cgminer.c b/cgminer.c |
10 | | index 8264db5..3bd4eb0 100644 |
11 | | +++ b/cgminer.c |
12 | | @@ -399,7 +399,7 @@ static char *set_int_1_to_10(const char *arg, int *i) |
13 | | return set_int_range(arg, i, 1, 10); |
14 | | } |
15 | | |
16 | | -#ifdef USE_BITFORCE |
17 | | +#if defined(USE_BITFORCE) || defined(USE_ICARUS) |
18 | | static char *add_serial(char *arg) |
19 | | { |
20 | | string_elist_add(arg, &scan_devices); |
21 | | @@ -661,7 +661,7 @@ static struct opt_table opt_config_table[] = { |
22 | | OPT_WITHOUT_ARG("--disable-gpu|-G", |
23 | | opt_set_bool, &opt_nogpu, |
24 | | "Disable GPU mining even if suitable devices exist"), |
25 | | -#if defined(WANT_CPUMINE) && (defined(HAVE_OPENCL) || defined(USE_BITFORCE)) |
26 | | +#if defined(WANT_CPUMINE) && (defined(HAVE_OPENCL) || defined(USE_BITFORCE) || defined(USE_ICARUS)) |
27 | | OPT_WITHOUT_ARG("--enable-cpu|-C", |
28 | | opt_set_bool, &opt_usecpu, |
29 | | "Enable CPU mining with other mining (default: no CPU mining if other devices exist)"), |
30 | | @@ -776,10 +776,10 @@ static struct opt_table opt_config_table[] = { |
31 | | OPT_WITHOUT_ARG("--round-robin", |
32 | | set_rr, &pool_strategy, |
33 | | "Change multipool strategy from failover to round robin on failure"), |
34 | | -#ifdef USE_BITFORCE |
35 | | +#if defined(USE_BITFORCE) || defined(USE_ICARUS) |
36 | | OPT_WITH_ARG("--scan-serial|-S", |
37 | | add_serial, NULL, NULL, |
38 | | - "Serial port to probe for BitForce device"), |
39 | | + "Serial port to probe for FPGA Mining device"), |
40 | | #endif |
41 | | OPT_WITH_ARG("--scan-time|-s", |
42 | | set_int_0_to_9999, opt_show_intval, &opt_scantime, |
43 | | @@ -961,6 +961,9 @@ static char *opt_verusage_and_exit(const char *extra) |
44 | | #ifdef USE_BITFORCE |
45 | | "bitforce " |
46 | | #endif |
47 | | +#ifdef USE_ICARUS |
48 | | + "icarus " |
49 | | +#endif |
50 | | "mining support.\n" |
51 | | , packagename); |
52 | | printf("%s", opt_usage(opt_argv0, extra)); |
53 | | @@ -4153,6 +4156,10 @@ struct device_api cpu_api = { |
54 | | extern struct device_api bitforce_api; |
55 | | #endif |
56 | | |
57 | | +#ifdef USE_ICARUS |
58 | | +extern struct device_api icarus_api; |
59 | | +#endif |
60 | | + |
61 | | |
62 | | static int cgminer_id_count = 0; |
63 | | |
64 | | @@ -4307,6 +4314,10 @@ int main (int argc, char *argv[]) |
65 | | bitforce_api.api_detect(); |
66 | | #endif |
67 | | |
68 | | +#ifdef USE_ICARUS |
69 | | + icarus_api.api_detect(); |
70 | | +#endif |
71 | | + |
72 | | #ifdef WANT_CPUMINE |
73 | | cpu_api.api_detect(); |
74 | | #endif |
75 | | 1.7.5.4 |
76 | | |
cgminer/patches/0004-add-Icarus-support-to-autoreconf-system.patch |
1 | | From 2bb92ebcdc4612d218e965b8f6f6f22b6b3ff21d Mon Sep 17 00:00:00 2001 |
2 | | From: Xiangfu <xiangfu@openmobilefree.net> |
3 | | Date: Mon, 13 Feb 2012 16:04:13 +0800 |
4 | | Subject: [PATCH 4/7] add Icarus support to autoreconf system |
5 | | |
6 | | Makefile.am | 3 +++ |
7 | | configure.ac | 21 +++++++++++++++++++-- |
8 | | 2 files changed, 22 insertions(+), 2 deletions(-) |
9 | | |
10 | | diff --git a/Makefile.am b/Makefile.am |
11 | | index 4249d51..5262d52 100644 |
12 | | +++ b/Makefile.am |
13 | | @@ -70,3 +70,6 @@ if HAS_BITFORCE |
14 | | cgminer_SOURCES += bitforce.c |
15 | | endif |
16 | | |
17 | | +if HAS_ICARUS |
18 | | +cgminer_SOURCES += icarus.c |
19 | | +endif |
20 | | diff --git a/configure.ac b/configure.ac |
21 | | index d2fdbb4..ce89c6f 100644 |
22 | | +++ b/configure.ac |
23 | | @@ -196,6 +196,17 @@ if test "x$bitforce" = xyes; then |
24 | | fi |
25 | | AM_CONDITIONAL([HAS_BITFORCE], [test x$bitforce = xyes]) |
26 | | |
27 | | +icarus="no" |
28 | | + |
29 | | +AC_ARG_ENABLE([icarus], |
30 | | + [AC_HELP_STRING([--enable-icarus],[Compile support for Icarus (default disabled)])], |
31 | | + [icarus=$enableval] |
32 | | + ) |
33 | | +if test "x$icarus" = xyes; then |
34 | | + AC_DEFINE([USE_ICARUS], [1], [Defined to 1 if Icarus support is wanted]) |
35 | | +fi |
36 | | +AM_CONDITIONAL([HAS_ICARUS], [test x$icarus = xyes]) |
37 | | + |
38 | | AC_SEARCH_LIBS(addstr, ncurses pdcurses, , |
39 | | AC_MSG_ERROR([Could not find curses library - please install libncurses-dev or pdcurses-dev])) |
40 | | |
41 | | @@ -338,13 +349,13 @@ if test "x$opencl" != xno; then |
42 | | echo " OpenCL...............: FOUND. GPU mining support enabled" |
43 | | else |
44 | | echo " OpenCL...............: NOT FOUND. GPU mining support DISABLED" |
45 | | - if test "x$cpumining$bitforce" = xnono; then |
46 | | + if test "x$cpumining$bitforce$icarus" = xnonono; then |
47 | | AC_MSG_ERROR([No mining configured in]) |
48 | | fi |
49 | | fi |
50 | | else |
51 | | echo " OpenCL...............: Detection overrided. GPU mining support DISABLED" |
52 | | - if test "x$cpumining$bitforce" = xnono; then |
53 | | + if test "x$cpumining$bitforce$icarus" = xnonono; then |
54 | | AC_MSG_ERROR([No mining configured in]) |
55 | | fi |
56 | | fi |
57 | | @@ -366,6 +377,12 @@ else |
58 | | echo " BitForce.FPGAs.......: Disabled" |
59 | | fi |
60 | | |
61 | | +if test "x$icarus" = xyes; then |
62 | | + echo " Icarus.FPGAs.........: Enabled" |
63 | | +else |
64 | | + echo " Icarus.FPGAs.........: Disabled" |
65 | | +fi |
66 | | + |
67 | | echo |
68 | | if test "x$cpumining" = xyes; then |
69 | | echo " CPU Mining...........: Enabled" |
70 | | 1.7.5.4 |
71 | | |