|
|
@ -54,6 +54,7 @@ static bool libztex_checkDevice (struct libusb_device *dev) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!(desc.idVendor == LIBZTEX_IDVENDOR && desc.idProduct == LIBZTEX_IDPRODUCT)) { |
|
|
|
if (!(desc.idVendor == LIBZTEX_IDVENDOR && desc.idProduct == LIBZTEX_IDPRODUCT)) { |
|
|
|
|
|
|
|
applog(LOG_DEBUG, "Not a ZTEX device %0.4x:%0.4x", desc.idVendor, desc.idProduct); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
@ -61,9 +62,8 @@ static bool libztex_checkDevice (struct libusb_device *dev) { |
|
|
|
|
|
|
|
|
|
|
|
static bool libztex_checkCapability (struct libztex_device *ztex, int i, int j) { |
|
|
|
static bool libztex_checkCapability (struct libztex_device *ztex, int i, int j) { |
|
|
|
if (!((i>=0) && (i<=5) && (j>=0) && (j<8) && |
|
|
|
if (!((i>=0) && (i<=5) && (j>=0) && (j<8) && |
|
|
|
(((ztex->interfaceCapabilities[i] & 255) & (1 << j)) != 0))) { |
|
|
|
(((ztex->interfaceCapabilities[i] & 255) & (1 << j)) != 0))) |
|
|
|
applog(LOG_ERR, "%s: capability missing: %d %d", ztex->repr, i, i); |
|
|
|
applog(LOG_ERR, "%s: capability missing: %d %d", ztex->repr, i, i); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -99,20 +99,19 @@ static void libztex_swapBits (unsigned char *buf, int size) { |
|
|
|
static int libztex_getFpgaState (struct libztex_device *ztex, struct libztex_fpgastate *state) { |
|
|
|
static int libztex_getFpgaState (struct libztex_device *ztex, struct libztex_fpgastate *state) { |
|
|
|
int cnt; |
|
|
|
int cnt; |
|
|
|
unsigned char buf[9]; |
|
|
|
unsigned char buf[9]; |
|
|
|
if (!libztex_checkCapability(ztex, CAPABILITY_FPGA)) { |
|
|
|
if (!libztex_checkCapability(ztex, CAPABILITY_FPGA)) |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x30, 0, 0, buf, 9, 1000); |
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x30, 0, 0, buf, 9, 1000); |
|
|
|
if (unlikely(cnt < 0)) { |
|
|
|
if (unlikely(cnt < 0)) { |
|
|
|
applog(LOG_ERR, "%s: Failed getFpgaState with err %d", ztex->repr, cnt); |
|
|
|
applog(LOG_ERR, "%s: Failed getFpgaState with err %d", ztex->repr, cnt); |
|
|
|
return cnt; |
|
|
|
return cnt; |
|
|
|
} |
|
|
|
} |
|
|
|
state->fpgaConfigured = buf[0] == 0; |
|
|
|
state->fpgaConfigured = (buf[0] == 0); |
|
|
|
state->fpgaChecksum = buf[1] & 0xff; |
|
|
|
state->fpgaChecksum = buf[1] & 0xff; |
|
|
|
state->fpgaBytes = ((buf[5] & 0xff)<<24) | ((buf[4] & 0xff)<<16) | ((buf[3] & 0xff)<<8) | (buf[2] & 0xff); |
|
|
|
state->fpgaBytes = ((buf[5] & 0xff)<<24) | ((buf[4] & 0xff)<<16) | ((buf[3] & 0xff)<<8) | (buf[2] & 0xff); |
|
|
|
state->fpgaInitB = buf[6] & 0xff; |
|
|
|
state->fpgaInitB = buf[6] & 0xff; |
|
|
|
state->fpgaFlashResult = buf[7]; |
|
|
|
state->fpgaFlashResult = buf[7]; |
|
|
|
state->fpgaFlashBitSwap = buf[8] != 0; |
|
|
|
state->fpgaFlashBitSwap = (buf[8] != 0); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -124,16 +123,14 @@ static int libztex_configureFpgaLS (struct libztex_device *ztex, const char* fir |
|
|
|
int tries, cnt, buf_p, i; |
|
|
|
int tries, cnt, buf_p, i; |
|
|
|
FILE *fp; |
|
|
|
FILE *fp; |
|
|
|
|
|
|
|
|
|
|
|
if (!libztex_checkCapability(ztex, CAPABILITY_FPGA)) { |
|
|
|
if (!libztex_checkCapability(ztex, CAPABILITY_FPGA)) |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
libztex_getFpgaState(ztex, &state); |
|
|
|
libztex_getFpgaState(ztex, &state); |
|
|
|
if (!force) { |
|
|
|
if (!force && state.fpgaConfigured) { |
|
|
|
if (state.fpgaConfigured) { |
|
|
|
applog(LOG_DEBUG, "Bitstream already configured"); |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (tries=10; tries>0; tries--) { |
|
|
|
for (tries=10; tries>0; tries--) { |
|
|
|
|
|
|
|
|
|
|
@ -151,7 +148,7 @@ static int libztex_configureFpgaLS (struct libztex_device *ztex, const char* fir |
|
|
|
if (feof(fp)) |
|
|
|
if (feof(fp)) |
|
|
|
pos--; |
|
|
|
pos--; |
|
|
|
|
|
|
|
|
|
|
|
if ( bs<0 || bs>1 ) |
|
|
|
if ( bs != 0 && bs != 1 ) |
|
|
|
bs = libztex_detectBitstreamBitOrder(buf, transactionBytes<pos ? transactionBytes : pos); |
|
|
|
bs = libztex_detectBitstreamBitOrder(buf, transactionBytes<pos ? transactionBytes : pos); |
|
|
|
|
|
|
|
|
|
|
|
//* Reset fpga
|
|
|
|
//* Reset fpga
|
|
|
@ -201,7 +198,7 @@ static int libztex_configureFpgaLS (struct libztex_device *ztex, const char* fir |
|
|
|
return 3; |
|
|
|
return 3; |
|
|
|
} |
|
|
|
} |
|
|
|
usleep(200000); |
|
|
|
usleep(200000); |
|
|
|
applog(LOG_ERR, "%s: FPGA configuration done", ztex->repr); |
|
|
|
applog(LOG_INFO, "%s: FPGA configuration done", ztex->repr); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -218,9 +215,8 @@ int libztex_configureFpga (struct libztex_device *ztex) { |
|
|
|
|
|
|
|
|
|
|
|
int libztex_setFreq (struct libztex_device *ztex, uint16_t freq) { |
|
|
|
int libztex_setFreq (struct libztex_device *ztex, uint16_t freq) { |
|
|
|
int cnt; |
|
|
|
int cnt; |
|
|
|
if (freq > ztex->freqMaxM) { |
|
|
|
if (freq > ztex->freqMaxM) |
|
|
|
freq = ztex->freqMaxM; |
|
|
|
freq = ztex->freqMaxM; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x83, freq, 0, NULL, 0, 500); |
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x83, freq, 0, NULL, 0, 500); |
|
|
|
if (unlikely(cnt < 0)) { |
|
|
|
if (unlikely(cnt < 0)) { |
|
|
@ -317,8 +313,8 @@ int libztex_prepare_device (struct libusb_device *dev, struct libztex_device** z |
|
|
|
return cnt; |
|
|
|
return cnt; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!(buf[0]) == 4)) { |
|
|
|
if (unlikely(buf[0] != 4)) { |
|
|
|
if (unlikely(buf[0]) != 2) { |
|
|
|
if (unlikely(buf[0] != 2)) { |
|
|
|
applog(LOG_ERR, "Invalid BTCMiner descriptor version. Firmware must be updated (%d).", buf[0]); |
|
|
|
applog(LOG_ERR, "Invalid BTCMiner descriptor version. Firmware must be updated (%d).", buf[0]); |
|
|
|
return 3; |
|
|
|
return 3; |
|
|
|
} |
|
|
|
} |
|
|
@ -393,9 +389,8 @@ int libztex_scanDevices (struct libztex_dev_list*** devs_p) { |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < found; i++) { |
|
|
|
for (i = 0; i < found; i++) { |
|
|
|
err = libztex_prepare_device(list[usbdevices[i]], &ztex); |
|
|
|
err = libztex_prepare_device(list[usbdevices[i]], &ztex); |
|
|
|
if (unlikely(err != 0)) { |
|
|
|
if (unlikely(err != 0)) |
|
|
|
applog(LOG_ERR, "prepare device: %d", err); |
|
|
|
applog(LOG_ERR, "prepare device: %d", err); |
|
|
|
} |
|
|
|
|
|
|
|
// check if valid
|
|
|
|
// check if valid
|
|
|
|
if (!ztex->valid) { |
|
|
|
if (!ztex->valid) { |
|
|
|
libztex_destroy_device(ztex); |
|
|
|
libztex_destroy_device(ztex); |
|
|
@ -404,9 +399,8 @@ int libztex_scanDevices (struct libztex_dev_list*** devs_p) { |
|
|
|
devs[pos] = malloc(sizeof(struct libztex_dev_list)); |
|
|
|
devs[pos] = malloc(sizeof(struct libztex_dev_list)); |
|
|
|
devs[pos]->dev = ztex; |
|
|
|
devs[pos]->dev = ztex; |
|
|
|
devs[pos]->next = NULL; |
|
|
|
devs[pos]->next = NULL; |
|
|
|
if (pos > 0) { |
|
|
|
if (pos > 0) |
|
|
|
devs[pos-1]->next = devs[pos]; |
|
|
|
devs[pos-1]->next = devs[pos]; |
|
|
|
} |
|
|
|
|
|
|
|
pos++; |
|
|
|
pos++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -417,13 +411,11 @@ int libztex_scanDevices (struct libztex_dev_list*** devs_p) { |
|
|
|
|
|
|
|
|
|
|
|
int libztex_sendHashData (struct libztex_device *ztex, unsigned char *sendbuf) { |
|
|
|
int libztex_sendHashData (struct libztex_device *ztex, unsigned char *sendbuf) { |
|
|
|
int cnt; |
|
|
|
int cnt; |
|
|
|
if (ztex == NULL || ztex->hndl == NULL) { |
|
|
|
if (ztex == NULL || ztex->hndl == NULL) |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x80, 0, 0, sendbuf, 44, 1000); |
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0x40, 0x80, 0, 0, sendbuf, 44, 1000); |
|
|
|
if (unlikely(cnt < 0)) { |
|
|
|
if (unlikely(cnt < 0)) |
|
|
|
applog(LOG_ERR, "%s: Failed sendHashData with err %d", ztex->repr, cnt); |
|
|
|
applog(LOG_ERR, "%s: Failed sendHashData with err %d", ztex->repr, cnt); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return cnt; |
|
|
|
return cnt; |
|
|
|
} |
|
|
|
} |
|
|
@ -433,9 +425,8 @@ int libztex_readHashData (struct libztex_device *ztex, struct libztex_hash_data |
|
|
|
unsigned char rbuf[12*8]; |
|
|
|
unsigned char rbuf[12*8]; |
|
|
|
int cnt, i; |
|
|
|
int cnt, i; |
|
|
|
|
|
|
|
|
|
|
|
if (ztex->hndl == NULL) { |
|
|
|
if (ztex->hndl == NULL) |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x81, 0, 0, rbuf, 12*ztex->numNonces, 1000); |
|
|
|
cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x81, 0, 0, rbuf, 12*ztex->numNonces, 1000); |
|
|
|
if (unlikely(cnt < 0)) { |
|
|
|
if (unlikely(cnt < 0)) { |
|
|
@ -458,9 +449,8 @@ void libztex_freeDevList (struct libztex_dev_list **devs) { |
|
|
|
ssize_t cnt = 0; |
|
|
|
ssize_t cnt = 0; |
|
|
|
bool done = false; |
|
|
|
bool done = false; |
|
|
|
while (!done) { |
|
|
|
while (!done) { |
|
|
|
if (devs[cnt]->next == NULL) { |
|
|
|
if (devs[cnt]->next == NULL) |
|
|
|
done = true; |
|
|
|
done = true; |
|
|
|
} |
|
|
|
|
|
|
|
free(devs[cnt++]); |
|
|
|
free(devs[cnt++]); |
|
|
|
} |
|
|
|
} |
|
|
|
free(devs); |
|
|
|
free(devs); |
|
|
|