|
|
@@ -81,8 +81,9 @@ _bailout(int fd, struct cgpu_info*modminer, int prio, const char *fmt, ...)
|
|
|
if (fd != -1)
|
|
|
serial_close(fd);
|
|
|
if (modminer) {
|
|
|
- modminer->device_fd = -1;
|
|
|
- mutex_unlock(&modminer->device_mutex);
|
|
|
+ pthread_mutex_t *mutexp = &modminer->device->device_mutex;
|
|
|
+ modminer->device->device_fd = -1;
|
|
|
+ mutex_unlock(mutexp);
|
|
|
}
|
|
|
|
|
|
va_list ap;
|
|
|
@@ -139,6 +140,7 @@ modminer_detect_one(const char *devpath)
|
|
|
modminer->device_path = strdup(devpath);
|
|
|
modminer->device_fd = -1;
|
|
|
modminer->deven = DEV_ENABLED;
|
|
|
+ modminer->procs = buf[0];
|
|
|
modminer->threads = buf[0];
|
|
|
modminer->name = devname;
|
|
|
modminer->cutofftemp = 85;
|
|
|
@@ -167,20 +169,20 @@ modminer_detect()
|
|
|
static bool
|
|
|
modminer_reopen(struct cgpu_info*modminer)
|
|
|
{
|
|
|
- close(modminer->device_fd);
|
|
|
+ close(modminer->device->device_fd);
|
|
|
int fd = serial_open(modminer->device_path, 0, 10, true);
|
|
|
if (unlikely(-1 == fd)) {
|
|
|
- applog(LOG_ERR, "%s %u: Failed to reopen %s", modminer->api->name, modminer->device_id, modminer->device_path);
|
|
|
+ applog(LOG_ERR, "%s: Failed to reopen %s", modminer->dev_repr, modminer->device_path);
|
|
|
return false;
|
|
|
}
|
|
|
- modminer->device_fd = fd;
|
|
|
+ modminer->device->device_fd = fd;
|
|
|
return true;
|
|
|
}
|
|
|
#define safebailout() do { \
|
|
|
bool _safebailoutrv; \
|
|
|
state->work_running = false; \
|
|
|
_safebailoutrv = modminer_reopen(modminer); \
|
|
|
- mutex_unlock(&modminer->device_mutex); \
|
|
|
+ mutex_unlock(mutexp); \
|
|
|
return _safebailoutrv ? 0 : -1; \
|
|
|
} while(0)
|
|
|
|
|
|
@@ -207,9 +209,9 @@ FD_ZERO(&fds); \
|
|
|
FD_SET(fd, &fds); \
|
|
|
select(fd+1, &fds, NULL, NULL, NULL); \
|
|
|
if (1 != read(fd, buf, 1)) \
|
|
|
- bailout2(LOG_ERR, "%s %u: Error programming %s (" eng ")", modminer->api->name, modminer->device_id, modminer->device_path); \
|
|
|
+ bailout2(LOG_ERR, "%s: Error programming %s (" eng ")", modminer->dev_repr, modminer->device_path); \
|
|
|
if (buf[0] != 1) \
|
|
|
- bailout2(LOG_ERR, "%s %u: Wrong " eng " programming %s", modminer->api->name, modminer->device_id, modminer->device_path); \
|
|
|
+ bailout2(LOG_ERR, "%s: Wrong " eng " programming %s", modminer->dev_repr, modminer->device_path); \
|
|
|
} while(0)
|
|
|
|
|
|
static bool
|
|
|
@@ -220,14 +222,14 @@ modminer_fpga_upload_bitstream(struct cgpu_info*modminer)
|
|
|
char buf[0x100];
|
|
|
unsigned long len, flen;
|
|
|
char fpgaid = FPGAID_ALL;
|
|
|
- FILE *f = open_xilinx_bitstream(modminer, BITSTREAM_FILENAME, &len);
|
|
|
+ FILE *f = open_xilinx_bitstream(modminer->api->dname, modminer->dev_repr, BITSTREAM_FILENAME, &len);
|
|
|
if (!f)
|
|
|
return false;
|
|
|
|
|
|
flen = len;
|
|
|
- int fd = modminer->device_fd;
|
|
|
+ int fd = modminer->device->device_fd;
|
|
|
|
|
|
- applog(LOG_WARNING, "%s %u: Programming %s... DO NOT EXIT UNTIL COMPLETE", modminer->api->name, modminer->device_id, modminer->device_path);
|
|
|
+ applog(LOG_WARNING, "%s: Programming %s... DO NOT EXIT UNTIL COMPLETE", modminer->dev_repr, modminer->device_path);
|
|
|
buf[0] = MODMINER_PROGRAM;
|
|
|
buf[1] = fpgaid;
|
|
|
buf[2] = (len >> 0) & 0xff;
|
|
|
@@ -235,27 +237,27 @@ modminer_fpga_upload_bitstream(struct cgpu_info*modminer)
|
|
|
buf[4] = (len >> 16) & 0xff;
|
|
|
buf[5] = (len >> 24) & 0xff;
|
|
|
if (6 != write(fd, buf, 6))
|
|
|
- bailout2(LOG_ERR, "%s %u: Error programming %s (cmd)", modminer->api->name, modminer->device_id, modminer->device_path);
|
|
|
+ bailout2(LOG_ERR, "%s: Error programming %s (cmd)", modminer->dev_repr, modminer->device_path);
|
|
|
status_read("cmd reply");
|
|
|
ssize_t buflen;
|
|
|
char nextstatus = 10;
|
|
|
while (len) {
|
|
|
buflen = len < 32 ? len : 32;
|
|
|
if (fread(buf, buflen, 1, f) != 1)
|
|
|
- bailout2(LOG_ERR, "%s %u: File underrun programming %s (%d bytes left)", modminer->api->name, modminer->device_id, modminer->device_path, len);
|
|
|
+ bailout2(LOG_ERR, "%s: File underrun programming %s (%d bytes left)", modminer->dev_repr, modminer->device_path, len);
|
|
|
if (write(fd, buf, buflen) != buflen)
|
|
|
- bailout2(LOG_ERR, "%s %u: Error programming %s (data)", modminer->api->name, modminer->device_id, modminer->device_path);
|
|
|
+ bailout2(LOG_ERR, "%s: Error programming %s (data)", modminer->dev_repr, modminer->device_path);
|
|
|
state->pdone = 100 - ((len * 100) / flen);
|
|
|
if (state->pdone >= nextstatus)
|
|
|
{
|
|
|
nextstatus += 10;
|
|
|
- applog(LOG_WARNING, "%s %u: Programming %s... %d%% complete...", modminer->api->name, modminer->device_id, modminer->device_path, state->pdone);
|
|
|
+ applog(LOG_WARNING, "%s: Programming %s... %d%% complete...", modminer->dev_repr, modminer->device_path, state->pdone);
|
|
|
}
|
|
|
status_read("status");
|
|
|
len -= buflen;
|
|
|
}
|
|
|
status_read("final status");
|
|
|
- applog(LOG_WARNING, "%s %u: Done programming %s", modminer->api->name, modminer->device_id, modminer->device_path);
|
|
|
+ applog(LOG_WARNING, "%s: Done programming %s", modminer->dev_repr, modminer->device_path);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
@@ -265,10 +267,10 @@ modminer_device_prepare(struct cgpu_info *modminer)
|
|
|
{
|
|
|
int fd = serial_open(modminer->device_path, 0, 10, true);
|
|
|
if (unlikely(-1 == fd))
|
|
|
- bailout(LOG_ERR, "%s %u: Failed to open %s", modminer->api->name, modminer->device_id, modminer->device_path);
|
|
|
+ bailout(LOG_ERR, "%s: Failed to open %s", modminer->dev_repr, modminer->device_path);
|
|
|
|
|
|
- modminer->device_fd = fd;
|
|
|
- applog(LOG_INFO, "%s %u: Opened %s", modminer->api->name, modminer->device_id, modminer->device_path);
|
|
|
+ modminer->device->device_fd = fd;
|
|
|
+ applog(LOG_INFO, "%s: Opened %s", modminer->dev_repr, modminer->device_path);
|
|
|
|
|
|
struct timeval now;
|
|
|
gettimeofday(&now, NULL);
|
|
|
@@ -282,17 +284,18 @@ modminer_device_prepare(struct cgpu_info *modminer)
|
|
|
static bool
|
|
|
modminer_fpga_prepare(struct thr_info *thr)
|
|
|
{
|
|
|
- struct cgpu_info *modminer = thr->cgpu;
|
|
|
+ struct cgpu_info *proc = thr->cgpu;
|
|
|
+ struct cgpu_info *modminer = proc->device;
|
|
|
|
|
|
// Don't need to lock the mutex here, since prepare runs from the main thread before the miner threads start
|
|
|
- if (modminer->device_fd == -1 && !modminer_device_prepare(modminer))
|
|
|
+ if (modminer->device->device_fd == -1 && !modminer_device_prepare(modminer))
|
|
|
return false;
|
|
|
|
|
|
struct modminer_fpga_state *state;
|
|
|
state = thr->cgpu_data = calloc(1, sizeof(struct modminer_fpga_state));
|
|
|
dclk_prepare(&state->dclk);
|
|
|
state->next_work_cmd[0] = MODMINER_SEND_WORK;
|
|
|
- state->next_work_cmd[1] = thr->device_thread; // FPGA id
|
|
|
+ state->next_work_cmd[1] = proc->proc_id; // FPGA id
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
@@ -302,7 +305,8 @@ modminer_change_clock(struct thr_info*thr, bool needlock, signed char delta)
|
|
|
{
|
|
|
struct cgpu_info*modminer = thr->cgpu;
|
|
|
struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
- char fpgaid = thr->device_thread;
|
|
|
+ char fpgaid = modminer->proc_id;
|
|
|
+ pthread_mutex_t *mutexp = &modminer->device->device_mutex;
|
|
|
int fd;
|
|
|
unsigned char cmd[6], buf[1];
|
|
|
unsigned char clk;
|
|
|
@@ -315,14 +319,14 @@ modminer_change_clock(struct thr_info*thr, bool needlock, signed char delta)
|
|
|
cmd[3] = cmd[4] = cmd[5] = '\0';
|
|
|
|
|
|
if (needlock)
|
|
|
- mutex_lock(&modminer->device_mutex);
|
|
|
- fd = modminer->device_fd;
|
|
|
+ mutex_lock(mutexp);
|
|
|
+ fd = modminer->device->device_fd;
|
|
|
if (6 != write(fd, cmd, 6))
|
|
|
- bailout2(LOG_ERR, "%s %u.%u: Error writing (set frequency)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ bailout2(LOG_ERR, "%s: Error writing (set frequency)", modminer->proc_repr);
|
|
|
if (serial_read(fd, &buf, 1) != 1)
|
|
|
- bailout2(LOG_ERR, "%s %u.%u: Error reading (set frequency)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ bailout2(LOG_ERR, "%s: Error reading (set frequency)", modminer->proc_repr);
|
|
|
if (needlock)
|
|
|
- mutex_unlock(&modminer->device_mutex);
|
|
|
+ mutex_unlock(mutexp);
|
|
|
|
|
|
if (buf[0])
|
|
|
state->dclk.freqM = clk / 2;
|
|
|
@@ -335,16 +339,13 @@ modminer_change_clock(struct thr_info*thr, bool needlock, signed char delta)
|
|
|
static bool modminer_dclk_change_clock(struct thr_info*thr, int multiplier)
|
|
|
{
|
|
|
struct cgpu_info *modminer = thr->cgpu;
|
|
|
- char fpgaid = thr->device_thread;
|
|
|
struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
uint8_t oldFreq = state->dclk.freqM;
|
|
|
signed char delta = (multiplier - oldFreq) * 2;
|
|
|
if (unlikely(!modminer_change_clock(thr, true, delta)))
|
|
|
return false;
|
|
|
|
|
|
- char repr[0x10];
|
|
|
- sprintf(repr, "%s %u.%u", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
- dclk_msg_freqchange(repr, oldFreq * 2, state->dclk.freqM * 2, NULL);
|
|
|
+ dclk_msg_freqchange(modminer->proc_repr, oldFreq * 2, state->dclk.freqM * 2, NULL);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -361,15 +362,15 @@ modminer_reduce_clock(struct thr_info*thr, bool needlock)
|
|
|
|
|
|
static bool _modminer_get_nonce(struct cgpu_info*modminer, char fpgaid, uint32_t*nonce)
|
|
|
{
|
|
|
- int fd = modminer->device_fd;
|
|
|
+ int fd = modminer->device->device_fd;
|
|
|
char cmd[2] = {MODMINER_CHECK_WORK, fpgaid};
|
|
|
|
|
|
if (write(fd, cmd, 2) != 2) {
|
|
|
- applog(LOG_ERR, "%s %u: Error writing (get nonce %u)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ applog(LOG_ERR, "%s: Error writing (get nonce)", modminer->proc_repr);
|
|
|
return false;
|
|
|
}
|
|
|
if (4 != serial_read(fd, nonce, 4)) {
|
|
|
- applog(LOG_ERR, "%s %u: Short read (get nonce %u)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ applog(LOG_ERR, "%s: Short read (get nonce)", modminer->proc_repr);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
@@ -382,50 +383,51 @@ modminer_fpga_init(struct thr_info *thr)
|
|
|
struct cgpu_info *modminer = thr->cgpu;
|
|
|
struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
int fd;
|
|
|
- char fpgaid = thr->device_thread;
|
|
|
+ char fpgaid = modminer->proc_id;
|
|
|
+ pthread_mutex_t *mutexp = &modminer->device->device_mutex;
|
|
|
uint32_t nonce;
|
|
|
|
|
|
unsigned char cmd[2], buf[4];
|
|
|
|
|
|
- mutex_lock(&modminer->device_mutex);
|
|
|
- fd = modminer->device_fd;
|
|
|
+ mutex_lock(mutexp);
|
|
|
+ fd = modminer->device->device_fd;
|
|
|
if (fd == -1) {
|
|
|
// Died in another thread...
|
|
|
- mutex_unlock(&modminer->device_mutex);
|
|
|
+ mutex_unlock(mutexp);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
cmd[0] = MODMINER_GET_USERCODE;
|
|
|
cmd[1] = fpgaid;
|
|
|
if (write(fd, cmd, 2) != 2)
|
|
|
- bailout2(LOG_ERR, "%s %u.%u: Error writing (read USER code)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ bailout2(LOG_ERR, "%s: Error writing (read USER code)", modminer->proc_repr);
|
|
|
if (serial_read(fd, buf, 4) != 4)
|
|
|
- bailout2(LOG_ERR, "%s %u.%u: Error reading (read USER code)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ bailout2(LOG_ERR, "%s: Error reading (read USER code)", modminer->proc_repr);
|
|
|
|
|
|
if (memcmp(buf, BISTREAM_USER_ID, 4)) {
|
|
|
- applog(LOG_ERR, "%s %u.%u: FPGA not programmed", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ applog(LOG_ERR, "%s: FPGA not programmed", modminer->proc_repr);
|
|
|
if (!modminer_fpga_upload_bitstream(modminer))
|
|
|
return false;
|
|
|
} else if (opt_force_dev_init && modminer->status == LIFE_INIT) {
|
|
|
- applog(LOG_DEBUG, "%s %u.%u: FPGA is already programmed, but --force-dev-init is set",
|
|
|
- modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ applog(LOG_DEBUG, "%s: FPGA is already programmed, but --force-dev-init is set",
|
|
|
+ modminer->proc_repr);
|
|
|
if (!modminer_fpga_upload_bitstream(modminer))
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
- applog(LOG_DEBUG, "%s %u.%u: FPGA is already programmed :)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ applog(LOG_DEBUG, "%s: FPGA is already programmed :)", modminer->proc_repr);
|
|
|
state->pdone = 101;
|
|
|
|
|
|
state->dclk.freqM = MODMINER_MAX_CLOCK / 2 + 1; // Will be reduced immediately
|
|
|
while (1) {
|
|
|
if (state->dclk.freqM <= MODMINER_MIN_CLOCK / 2)
|
|
|
- bailout2(LOG_ERR, "%s %u.%u: Hit minimum trying to find acceptable frequencies", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ bailout2(LOG_ERR, "%s: Hit minimum trying to find acceptable frequencies", modminer->proc_repr);
|
|
|
--state->dclk.freqM;
|
|
|
if (!modminer_change_clock(thr, false, 0))
|
|
|
// MCU rejected assignment
|
|
|
continue;
|
|
|
if (!_modminer_get_nonce(modminer, fpgaid, &nonce))
|
|
|
- bailout2(LOG_ERR, "%s %u.%u: Error detecting acceptable frequencies", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ bailout2(LOG_ERR, "%s: Error detecting acceptable frequencies", modminer->proc_repr);
|
|
|
if (!memcmp(&nonce, "\x00\xff\xff\xff", 4))
|
|
|
// MCU took assignment, but disabled FPGA
|
|
|
continue;
|
|
|
@@ -435,39 +437,66 @@ modminer_fpga_init(struct thr_info *thr)
|
|
|
state->dclk.freqMaxM = state->dclk.freqM;
|
|
|
if (MODMINER_DEF_CLOCK / 2 < state->dclk.freqM) {
|
|
|
if (!modminer_change_clock(thr, false, -(state->dclk.freqM * 2 - MODMINER_DEF_CLOCK)))
|
|
|
- applog(LOG_WARNING, "%s %u.%u: Failed to set desired initial frequency of %u", modminer->api->name, modminer->device_id, fpgaid, MODMINER_DEF_CLOCK);
|
|
|
+ applog(LOG_WARNING, "%s: Failed to set desired initial frequency of %u", modminer->proc_repr, MODMINER_DEF_CLOCK);
|
|
|
}
|
|
|
state->dclk.freqMDefault = state->dclk.freqM;
|
|
|
- applog(LOG_WARNING, "%s %u.%u: Frequency set to %u MHz (range: %u-%u)", modminer->api->name, modminer->device_id, fpgaid, state->dclk.freqM * 2, MODMINER_MIN_CLOCK, state->dclk.freqMaxM * 2);
|
|
|
+ applog(LOG_WARNING, "%s: Frequency set to %u MHz (range: %u-%u)", modminer->proc_repr, state->dclk.freqM * 2, MODMINER_MIN_CLOCK, state->dclk.freqMaxM * 2);
|
|
|
|
|
|
- mutex_unlock(&modminer->device_mutex);
|
|
|
+ mutex_unlock(mutexp);
|
|
|
|
|
|
thr->primary_thread = true;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-get_modminer_statline_before(char *buf, struct cgpu_info *modminer)
|
|
|
+static
|
|
|
+bool get_modminer_upload_percent(char *buf, struct cgpu_info *modminer)
|
|
|
{
|
|
|
char info[18] = " | ";
|
|
|
- int tc = modminer->threads;
|
|
|
- bool havetemp = false;
|
|
|
- int i;
|
|
|
|
|
|
- char pdone = ((struct modminer_fpga_state*)(modminer->thr[0]->cgpu_data))->pdone;
|
|
|
+ char pdone = ((struct modminer_fpga_state*)(modminer->device->thr[0]->cgpu_data))->pdone;
|
|
|
if (pdone != 101) {
|
|
|
sprintf(&info[1], "%3d%%", pdone);
|
|
|
info[5] = ' ';
|
|
|
strcat(buf, info);
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static
|
|
|
+void get_modminer_statline_before(char *buf, struct cgpu_info *modminer)
|
|
|
+{
|
|
|
+ if (get_modminer_upload_percent(buf, modminer))
|
|
|
+ return;
|
|
|
+
|
|
|
+ struct thr_info*thr = modminer->thr[0];
|
|
|
+ struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
+ float gt = state->temp;
|
|
|
+
|
|
|
+ if (gt > 0)
|
|
|
+ tailsprintf(buf, "%5.1fC ", gt);
|
|
|
+ else
|
|
|
+ tailsprintf(buf, " ", gt);
|
|
|
+ tailsprintf(buf, " | ");
|
|
|
+}
|
|
|
+
|
|
|
+static
|
|
|
+void get_modminer_dev_statline_before(char *buf, struct cgpu_info *modminer)
|
|
|
+{
|
|
|
+ if (get_modminer_upload_percent(buf, modminer))
|
|
|
+ return;
|
|
|
+
|
|
|
+ char info[18] = " | ";
|
|
|
+ int tc = modminer->procs;
|
|
|
+ bool havetemp = false;
|
|
|
+ int i;
|
|
|
|
|
|
if (tc > 4)
|
|
|
tc = 4;
|
|
|
|
|
|
- for (i = tc - 1; i >= 0; --i) {
|
|
|
- struct thr_info*thr = modminer->thr[i];
|
|
|
+ for (i = 0; i < tc; ++i, modminer = modminer->next_proc) {
|
|
|
+ struct thr_info*thr = modminer->thr[0];
|
|
|
struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
unsigned char temp = state->temp;
|
|
|
|
|
|
@@ -498,8 +527,8 @@ static void modminer_get_temperature(struct cgpu_info *modminer, struct thr_info
|
|
|
return;
|
|
|
#endif
|
|
|
|
|
|
- int fd = modminer->device_fd;
|
|
|
- int fpgaid = thr->device_thread;
|
|
|
+ int fd = modminer->device->device_fd;
|
|
|
+ int fpgaid = modminer->proc_id;
|
|
|
char cmd[2] = {MODMINER_TEMP1, fpgaid};
|
|
|
char temperature;
|
|
|
|
|
|
@@ -513,8 +542,8 @@ static void modminer_get_temperature(struct cgpu_info *modminer, struct thr_info
|
|
|
state->last_cutoff_reduced = now;
|
|
|
int oldFreq = state->dclk.freqM;
|
|
|
if (modminer_reduce_clock(thr, false))
|
|
|
- applog(LOG_NOTICE, "%s %u.%u: Frequency %s from %u to %u MHz (temp: %d)",
|
|
|
- modminer->api->name, modminer->device_id, fpgaid,
|
|
|
+ applog(LOG_NOTICE, "%s: Frequency %s from %u to %u MHz (temp: %d)",
|
|
|
+ modminer->proc_repr,
|
|
|
(oldFreq > state->dclk.freqM ? "dropped" : "raised "),
|
|
|
oldFreq * 2, state->dclk.freqM * 2,
|
|
|
temperature
|
|
|
@@ -536,15 +565,19 @@ static void modminer_get_temperature(struct cgpu_info *modminer, struct thr_info
|
|
|
|
|
|
static bool modminer_get_stats(struct cgpu_info *modminer)
|
|
|
{
|
|
|
+ pthread_mutex_t *mutexp = &modminer->device->device_mutex;
|
|
|
int hottest = 0;
|
|
|
bool get_temp = (modminer->deven != DEV_ENABLED);
|
|
|
// Getting temperature more efficiently while enabled
|
|
|
- // NOTE: Don't need to mess with mutex here, since the device is disabled
|
|
|
for (int i = modminer->threads; i--; ) {
|
|
|
struct thr_info*thr = modminer->thr[i];
|
|
|
struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
if (get_temp)
|
|
|
+ {
|
|
|
+ mutex_lock(mutexp);
|
|
|
modminer_get_temperature(modminer, thr);
|
|
|
+ mutex_unlock(mutexp);
|
|
|
+ }
|
|
|
int temp = state->temp;
|
|
|
if (temp > hottest)
|
|
|
hottest = temp;
|
|
|
@@ -559,25 +592,24 @@ static struct api_data*
|
|
|
get_modminer_api_extra_device_status(struct cgpu_info*modminer)
|
|
|
{
|
|
|
struct api_data*root = NULL;
|
|
|
- static char *k[4] = {"Board0", "Board1", "Board2", "Board3"};
|
|
|
- int i;
|
|
|
+ struct thr_info*thr = modminer->thr[0];
|
|
|
+ struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
+ float f;
|
|
|
+ double d;
|
|
|
|
|
|
- for (i = modminer->threads - 1; i >= 0; --i) {
|
|
|
- struct thr_info*thr = modminer->thr[i];
|
|
|
- struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
- json_t *o = json_object();
|
|
|
-
|
|
|
- if (state->temp)
|
|
|
- json_object_set_new(o, "Temperature", json_integer(state->temp));
|
|
|
- json_object_set_new(o, "Frequency", json_real((double)state->dclk.freqM * 2 * 1000000.));
|
|
|
- json_object_set_new(o, "Cool Max Frequency", json_real((double)state->dclk.freqMaxM * 2 * 1000000.));
|
|
|
- json_object_set_new(o, "Max Frequency", json_real((double)state->freqMaxMaxM * 2 * 1000000.));
|
|
|
- json_object_set_new(o, "Hardware Errors", json_integer(state->bad_share_counter));
|
|
|
- json_object_set_new(o, "Valid Nonces", json_integer(state->good_share_counter));
|
|
|
-
|
|
|
- root = api_add_json(root, k[i], o, false);
|
|
|
- json_decref(o);
|
|
|
+ if (state->temp)
|
|
|
+ {
|
|
|
+ f = state->temp;
|
|
|
+ root = api_add_temp(root, "Temperature", &f, true);
|
|
|
}
|
|
|
+ d = (double)state->dclk.freqM * 2;
|
|
|
+ root = api_add_freq(root, "Frequency", &d, true);
|
|
|
+ d = (double)state->dclk.freqMaxM * 2;
|
|
|
+ root = api_add_freq(root, "Cool Max Frequency", &d, true);
|
|
|
+ d = (double)state->freqMaxMaxM * 2;
|
|
|
+ root = api_add_freq(root, "Max Frequency", &d, true);
|
|
|
+ root = api_add_int(root, "Hardware Errors", &state->bad_share_counter, true);
|
|
|
+ root = api_add_int(root, "Valid Nonces", &state->good_share_counter, true);
|
|
|
|
|
|
return root;
|
|
|
}
|
|
|
@@ -600,32 +632,32 @@ modminer_start_work(struct thr_info*thr)
|
|
|
fd_set fds;
|
|
|
struct cgpu_info*modminer = thr->cgpu;
|
|
|
struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
- char fpgaid = thr->device_thread;
|
|
|
+ pthread_mutex_t *mutexp = &modminer->device->device_mutex;
|
|
|
int fd;
|
|
|
|
|
|
char buf[1];
|
|
|
|
|
|
- mutex_lock(&modminer->device_mutex);
|
|
|
- fd = modminer->device_fd;
|
|
|
+ mutex_lock(mutexp);
|
|
|
+ fd = modminer->device->device_fd;
|
|
|
|
|
|
if (unlikely(fd == -1)) {
|
|
|
if (!modminer_reopen(modminer)) {
|
|
|
- mutex_unlock(&modminer->device_mutex);
|
|
|
+ mutex_unlock(mutexp);
|
|
|
return false;
|
|
|
}
|
|
|
- fd = modminer->device_fd;
|
|
|
+ fd = modminer->device->device_fd;
|
|
|
}
|
|
|
|
|
|
if (46 != write(fd, state->next_work_cmd, 46))
|
|
|
- bailout2(LOG_ERR, "%s %u.%u: Error writing (start work)", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ bailout2(LOG_ERR, "%s: Error writing (start work)", modminer->proc_repr);
|
|
|
gettimeofday(&state->tv_workstart, NULL);
|
|
|
state->hashes = 0;
|
|
|
status_read("start work");
|
|
|
- mutex_unlock(&modminer->device_mutex);
|
|
|
+ mutex_unlock(mutexp);
|
|
|
if (opt_debug) {
|
|
|
char *xdata = bin2hex(state->running_work.data, 80);
|
|
|
- applog(LOG_DEBUG, "%s %u.%u: Started work: %s",
|
|
|
- modminer->api->name, modminer->device_id, fpgaid, xdata);
|
|
|
+ applog(LOG_DEBUG, "%s: Started work: %s",
|
|
|
+ modminer->proc_repr, xdata);
|
|
|
free(xdata);
|
|
|
}
|
|
|
|
|
|
@@ -645,7 +677,8 @@ modminer_process_results(struct thr_info*thr)
|
|
|
{
|
|
|
struct cgpu_info*modminer = thr->cgpu;
|
|
|
struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
- char fpgaid = thr->device_thread;
|
|
|
+ char fpgaid = modminer->proc_id;
|
|
|
+ pthread_mutex_t *mutexp = &modminer->device->device_mutex;
|
|
|
struct work *work = &state->running_work;
|
|
|
|
|
|
uint32_t nonce;
|
|
|
@@ -653,27 +686,27 @@ modminer_process_results(struct thr_info*thr)
|
|
|
int immediate_bad_nonces = 0, immediate_nonces = 0;
|
|
|
bool bad;
|
|
|
|
|
|
- mutex_lock(&modminer->device_mutex);
|
|
|
+ mutex_lock(mutexp);
|
|
|
modminer_get_temperature(modminer, thr);
|
|
|
|
|
|
iter = 200;
|
|
|
while (1) {
|
|
|
if (!_modminer_get_nonce(modminer, fpgaid, &nonce))
|
|
|
safebailout();
|
|
|
- mutex_unlock(&modminer->device_mutex);
|
|
|
+ mutex_unlock(mutexp);
|
|
|
if (memcmp(&nonce, "\xff\xff\xff\xff", 4)) {
|
|
|
nonce = le32toh(nonce);
|
|
|
bad = !test_nonce(work, nonce, false);
|
|
|
++immediate_nonces;
|
|
|
if (!bad)
|
|
|
- applog(LOG_DEBUG, "%s %u.%u: Nonce for current work: %02x%02x%02x%02x",
|
|
|
- modminer->api->name, modminer->device_id, fpgaid,
|
|
|
+ applog(LOG_DEBUG, "%s: Nonce for current work: %02x%02x%02x%02x",
|
|
|
+ modminer->proc_repr,
|
|
|
NONCE_CHARS(nonce));
|
|
|
else
|
|
|
if (test_nonce(&state->last_work, nonce, false))
|
|
|
{
|
|
|
- applog(LOG_DEBUG, "%s %u.%u: Nonce for previous work: %02x%02x%02x%02x",
|
|
|
- modminer->api->name, modminer->device_id, fpgaid,
|
|
|
+ applog(LOG_DEBUG, "%s: Nonce for previous work: %02x%02x%02x%02x",
|
|
|
+ modminer->proc_repr,
|
|
|
NONCE_CHARS(nonce));
|
|
|
work = &state->last_work;
|
|
|
bad = false;
|
|
|
@@ -684,8 +717,8 @@ modminer_process_results(struct thr_info*thr)
|
|
|
submit_nonce(thr, work, nonce);
|
|
|
}
|
|
|
else {
|
|
|
- applog(LOG_DEBUG, "%s %u.%u: Nonce with H not zero : %02x%02x%02x%02x",
|
|
|
- modminer->api->name, modminer->device_id, fpgaid,
|
|
|
+ applog(LOG_DEBUG, "%s: Nonce with H not zero : %02x%02x%02x%02x",
|
|
|
+ modminer->proc_repr,
|
|
|
NONCE_CHARS(nonce));
|
|
|
++hw_errors;
|
|
|
++modminer->hw_errors;
|
|
|
@@ -698,7 +731,7 @@ modminer_process_results(struct thr_info*thr)
|
|
|
nmsleep(1);
|
|
|
if (work_restart(thr))
|
|
|
break;
|
|
|
- mutex_lock(&modminer->device_mutex);
|
|
|
+ mutex_lock(mutexp);
|
|
|
}
|
|
|
|
|
|
struct timeval tv_workend, elapsed;
|
|
|
@@ -708,7 +741,7 @@ modminer_process_results(struct thr_info*thr)
|
|
|
uint64_t hashes = (uint64_t)state->dclk.freqM * 2 * (((uint64_t)elapsed.tv_sec * 1000000) + elapsed.tv_usec);
|
|
|
if (hashes > 0xffffffff)
|
|
|
{
|
|
|
- applog(LOG_WARNING, "%s %u.%u: Finished work before new one sent", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
+ applog(LOG_WARNING, "%s: Finished work before new one sent", modminer->proc_repr);
|
|
|
hashes = 0xffffffff;
|
|
|
}
|
|
|
if (hashes <= state->hashes)
|
|
|
@@ -779,20 +812,8 @@ static char *modminer_set_device(struct cgpu_info *modminer, char *option, char
|
|
|
return replybuf;
|
|
|
}
|
|
|
|
|
|
- if (!strncasecmp(option, "clock", 5)) {
|
|
|
- char repr[0x10];
|
|
|
- int fpgaid, fpgaid_end, multiplier;
|
|
|
-
|
|
|
- if (option[5])
|
|
|
- fpgaid = fpgaid_end = abs(atoi(&option[5]));
|
|
|
- else {
|
|
|
- fpgaid = 0;
|
|
|
- fpgaid_end = modminer->threads - 1;
|
|
|
- }
|
|
|
- if (fpgaid >= modminer->threads) {
|
|
|
- sprintf(replybuf, "invalid fpga: '%s' valid range 0-%d", &option[5], modminer->threads - 1);
|
|
|
- return replybuf;
|
|
|
- }
|
|
|
+ if (strcasecmp(option, "clock") == 0) {
|
|
|
+ int multiplier;
|
|
|
|
|
|
if (!setting || !*setting) {
|
|
|
sprintf(replybuf, "missing clock setting");
|
|
|
@@ -807,22 +828,19 @@ static char *modminer_set_device(struct cgpu_info *modminer, char *option, char
|
|
|
}
|
|
|
|
|
|
multiplier = val / 2;
|
|
|
- for ( ; fpgaid <= fpgaid_end; ++fpgaid) {
|
|
|
- struct thr_info *thr = modminer->thr[fpgaid];
|
|
|
- struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
- uint8_t oldFreqM = state->dclk.freqM;
|
|
|
- signed char delta = (multiplier - oldFreqM) * 2;
|
|
|
- state->dclk.freqMDefault = multiplier;
|
|
|
- if (unlikely(!modminer_change_clock(thr, true, delta))) {
|
|
|
- sprintf(replybuf, "Set clock failed: %s %u.%u",
|
|
|
- modminer->api->name, modminer->device_id, fpgaid);
|
|
|
- return replybuf;
|
|
|
- }
|
|
|
-
|
|
|
- sprintf(repr, "%s %u.%u", modminer->api->name, modminer->device_id, fpgaid);
|
|
|
- dclk_msg_freqchange(repr, oldFreqM * 2, state->dclk.freqM * 2, " on user request");
|
|
|
+ struct thr_info *thr = modminer->thr[0];
|
|
|
+ struct modminer_fpga_state *state = thr->cgpu_data;
|
|
|
+ uint8_t oldFreqM = state->dclk.freqM;
|
|
|
+ signed char delta = (multiplier - oldFreqM) * 2;
|
|
|
+ state->dclk.freqMDefault = multiplier;
|
|
|
+ if (unlikely(!modminer_change_clock(thr, true, delta))) {
|
|
|
+ sprintf(replybuf, "Set clock failed: %s",
|
|
|
+ modminer->proc_repr);
|
|
|
+ return replybuf;
|
|
|
}
|
|
|
|
|
|
+ dclk_msg_freqchange(modminer->proc_repr, oldFreqM * 2, state->dclk.freqM * 2, " on user request");
|
|
|
+
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
@@ -834,6 +852,7 @@ struct device_api modminer_api = {
|
|
|
.dname = "modminer",
|
|
|
.name = "MMQ",
|
|
|
.api_detect = modminer_detect,
|
|
|
+ .get_dev_statline_before = get_modminer_dev_statline_before,
|
|
|
.get_statline_before = get_modminer_statline_before,
|
|
|
.get_stats = modminer_get_stats,
|
|
|
.get_api_extra_device_status = get_modminer_api_extra_device_status,
|