diff --git a/driver-ztex.c b/driver-ztex.c index a938caef..fc4b2439 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -30,17 +30,37 @@ #define GOLDEN_BACKLOG 5 -struct device_api ztex_api, ztex_hotplug_api; +struct device_api ztex_api; // Forward declarations static void ztex_disable(struct thr_info* thr); static bool ztex_prepare(struct thr_info *thr); +static void ztex_selectFpga(struct libztex_device* ztex) +{ + if (ztex->root->numberOfFpgas > 1) { + if (ztex->root->selectedFpga != ztex->fpgaNum) + mutex_lock(&ztex->root->mutex); + libztex_selectFpga(ztex); + } +} + +static void ztex_releaseFpga(struct libztex_device* ztex) +{ + if (ztex->root->numberOfFpgas > 1) { + ztex->root->selectedFpga = -1; + mutex_unlock(&ztex->root->mutex); + } +} + static void ztex_detect(void) { int cnt; - int i; + int i,j; + int fpgacount; struct libztex_dev_list **ztex_devices; + struct libztex_device *ztex_slave; + struct cgpu_info *ztex; cnt = libztex_scanDevices(&ztex_devices); applog(LOG_WARNING, "Found %d ztex board(s)", cnt); @@ -48,14 +68,30 @@ static void ztex_detect(void) for (i = 0; i < cnt; i++) { if (total_devices == MAX_DEVICES) break; - struct cgpu_info *ztex; ztex = calloc(1, sizeof(struct cgpu_info)); ztex->api = &ztex_api; ztex->device_ztex = ztex_devices[i]->dev; ztex->threads = 1; + ztex->device_ztex->fpgaNum = 0; + ztex->device_ztex->root = ztex->device_ztex; add_cgpu(ztex); - applog(LOG_WARNING,"%s: Found Ztex, mark as %d", ztex->device_ztex->repr, ztex->device_id); + fpgacount = libztex_numberOfFpgas(ztex->device_ztex); + + if (fpgacount > 1) + pthread_mutex_init(&ztex->device_ztex->mutex, NULL); + + for (j = 1; j < fpgacount; j++) { + ztex = calloc(1, sizeof(struct cgpu_info)); + ztex->api = &ztex_api; + ztex_slave = calloc(1, sizeof(struct libztex_device)); + memcpy(ztex_slave, ztex_devices[i]->dev, sizeof(struct libztex_device)); + ztex->device_ztex = ztex_slave; + ztex_slave->root = ztex_devices[i]->dev; + ztex_slave->fpgaNum = j; + } + + applog(LOG_WARNING,"%s: Found Ztex (fpga count = %d) , mark as %d", ztex->device_ztex->repr, fpgacount, ztex->device_id); } if (cnt > 0) @@ -88,16 +124,18 @@ static bool ztex_updateFreq(struct libztex_device* ztex) } if (bestM != ztex->freqM) { - libztex_selectFpga(ztex, 0); + ztex_selectFpga(ztex); libztex_setFreq(ztex, bestM); + ztex_releaseFpga(ztex); } maxM = ztex->freqMDefault; while (maxM < ztex->freqMaxM && ztex->errorWeight[maxM + 1] > 100) maxM++; if ((bestM < (1.0 - LIBZTEX_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) { - libztex_selectFpga(ztex, 0); + ztex_selectFpga(ztex); libztex_resetFpga(ztex); + ztex_releaseFpga(ztex); applog(LOG_ERR, "%s: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.", ztex->repr, (1.0 - 1.0 * bestM / maxM) * 100); return false; @@ -163,7 +201,7 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, memcpy(sendbuf, work->data + 64, 12); memcpy(sendbuf + 12, work->midstate, 32); - libztex_selectFpga(ztex, 0); + ztex_selectFpga(ztex); i = libztex_sendHashData(ztex, sendbuf); if (i < 0) { // Something wrong happened in send @@ -174,9 +212,11 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, // And there's nothing we can do about it ztex_disable(thr); applog(LOG_ERR, "%s: Failed to send hash data with err %d, giving up", ztex->repr, i); + ztex_releaseFpga(ztex); return 0; } } + ztex_releaseFpga(ztex); applog(LOG_DEBUG, "%s: sent hashdata", ztex->repr); @@ -204,7 +244,7 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, applog(LOG_DEBUG, "%s: New work detected", ztex->repr); break; } - libztex_selectFpga(ztex, 0); + ztex_selectFpga(ztex); i = libztex_readHashData(ztex, &hdata[0]); if (i < 0) { // Something wrong happened in read @@ -217,9 +257,11 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i); free(lastnonce); free(backlog); + ztex_releaseFpga(ztex); return 0; } } + ztex_releaseFpga(ztex); if (work_restart[thr->id].restart) { applog(LOG_DEBUG, "%s: New work detected", ztex->repr); @@ -310,24 +352,27 @@ static void ztex_statline_before(char *buf, struct cgpu_info *cgpu) static bool ztex_prepare(struct thr_info *thr) { struct timeval now; - struct cgpu_info *ztex = thr->cgpu; + struct cgpu_info *cgpu = thr->cgpu; + struct libztex_device *ztex = cgpu->device_ztex; gettimeofday(&now, NULL); - get_datestamp(ztex->init, &now); - - if (libztex_configureFpga(ztex->device_ztex) != 0) + get_datestamp(cgpu->init, &now); + + libztex_selectFpga(ztex); + if (libztex_configureFpga(ztex) != 0) return false; - - ztex->device_ztex->freqM = -1; - ztex_updateFreq(ztex->device_ztex); - - applog(LOG_DEBUG, "%s: prepare", ztex->device_ztex->repr); + ztex_releaseFpga(ztex); + ztex->freqM = -1; + ztex_updateFreq(ztex); + applog(LOG_DEBUG, "%s: prepare", ztex->repr); return true; } static void ztex_shutdown(struct thr_info *thr) { if (thr->cgpu->device_ztex != NULL) { + if (thr->cgpu->device_ztex->fpgaNum == 0) + pthread_mutex_destroy(&thr->cgpu->device_ztex->mutex); applog(LOG_DEBUG, "%s: shutdown", thr->cgpu->device_ztex->repr); libztex_destroy_device(thr->cgpu->device_ztex); thr->cgpu->device_ztex = NULL; @@ -350,3 +395,4 @@ struct device_api ztex_api = { .scanhash = ztex_scanhash, .thread_shutdown = ztex_shutdown, }; + diff --git a/libztex.c b/libztex.c index a73130fa..29a226ac 100644 --- a/libztex.c +++ b/libztex.c @@ -339,19 +339,20 @@ int libztex_numberOfFpgas(struct libztex_device *ztex) { return cnt; } ztex->numberOfFpgas = buf[0] + 1; - ztex->selectedFpga = buf[1]; + ztex->selectedFpga = -1;//buf[1]; ztex->parallelConfigSupport = (buf[2] == 1); } else { ztex->numberOfFpgas = 1; - ztex->selectedFpga = 0; + ztex->selectedFpga = -1;//0; ztex->parallelConfigSupport = false; } } return ztex->numberOfFpgas; } -int libztex_selectFpga(struct libztex_device *ztex, int number) { +int libztex_selectFpga(struct libztex_device *ztex) { int cnt, fpgacnt = libztex_numberOfFpgas(ztex); + int number = ztex->fpgaNum; if (number < 0 || number >= fpgacnt) { applog(LOG_WARNING, "%s: Trying to select wrong fpga (%d in %d)", ztex->repr, number, fpgacnt); return 1; @@ -380,8 +381,12 @@ int libztex_setFreq(struct libztex_device *ztex, uint16_t freq) { return cnt; } ztex->freqM = freq; - applog(LOG_WARNING, "%s: Frequency change from %0.2f to %0.2f Mhz", - ztex->repr, ztex->freqM1 * (oldfreq + 1), ztex->freqM1 * (ztex->freqM + 1)); + if (oldfreq == -1) + applog(LOG_WARNING, "%s: Frequency set to %0.2f Mhz", + ztex->repr, ztex->freqM1 * (ztex->freqM + 1)); + else + applog(LOG_WARNING, "%s: Frequency change from %0.2f to %0.2f Mhz", + ztex->repr, ztex->freqM1 * (oldfreq + 1), ztex->freqM1 * (ztex->freqM + 1)); return 0; } diff --git a/libztex.h b/libztex.h index f95fc990..287b618d 100644 --- a/libztex.h +++ b/libztex.h @@ -44,6 +44,9 @@ struct libztex_fpgastate { }; struct libztex_device { + pthread_mutex_t mutex; + struct libztex_device *root; + int fpgaNum; bool valid; struct libusb_device_descriptor descriptor; libusb_device_handle *hndl; @@ -98,6 +101,7 @@ extern int libztex_setFreq (struct libztex_device *ztex, uint16_t freq); extern int libztex_sendHashData (struct libztex_device *ztex, unsigned char *sendbuf); extern int libztex_readHashData (struct libztex_device *ztex, struct libztex_hash_data nonces[]); extern int libztex_resetFpga (struct libztex_device *ztex); -extern int libztex_selectFpga(struct libztex_device *ztex, int number); +extern int libztex_selectFpga(struct libztex_device *ztex); +extern int libztex_numberOfFpgas(struct libztex_device *ztex); #endif /* __LIBZTEX_H__ */