/ driver-cointerra.c
driver-cointerra.c
   1  /*
   2   * Copyright 2013-2014 Con Kolivas <kernel@kolivas.org>
   3   *
   4   * This program is free software; you can redistribute it and/or modify it
   5   * under the terms of the GNU General Public License as published by the Free
   6   * Software Foundation; either version 3 of the License, or (at your option)
   7   * any later version.  See COPYING for more details.
   8   */
   9  
  10  #include "config.h"
  11  
  12  #include "miner.h"
  13  #include "driver-cointerra.h"
  14  
  15  static const char *cointerra_hdr = "ZZ";
  16  
  17  int opt_ps_load;
  18  
  19  static void cta_gen_message(char *msg, char type)
  20  {
  21  	memset(msg, 0, CTA_MSG_SIZE);
  22  	memcpy(msg, cointerra_hdr, 2);
  23  	msg[CTA_MSG_TYPE] = type;
  24  }
  25  
  26  /* Find the number of leading zero bits in diff */
  27  static uint8_t diff_to_bits(double diff)
  28  {
  29  	uint64_t diff64;
  30  	uint8_t i;
  31  
  32  	diff /= 0.9999847412109375;
  33  	diff *= (double)2147483648.0;
  34  	if (diff > 0x8000000000000000ULL)
  35  		diff = 0x8000000000000000ULL;
  36  	/* Convert it to an integer */
  37  	diff64 = diff;
  38  	for (i = 0; diff64; i++, diff64 >>= 1);
  39  
  40  	return i;
  41  }
  42  
  43  static double bits_to_diff(uint8_t bits)
  44  {
  45  	double ret = 1.0;
  46  
  47  	if (likely(bits > 32))
  48  		ret *= 1ull << (bits - 32);
  49  	else if (unlikely(bits < 32))
  50  		ret /= 1ull << (32 - bits);
  51  	return ret;
  52  }
  53  
  54  static bool cta_reset_init(char *buf)
  55  {
  56  	return ((buf[CTA_MSG_TYPE] == CTA_RECV_RDONE) && ((buf[CTA_RESET_TYPE]&0x3) == CTA_RESET_INIT));
  57  }
  58  
  59  static char *mystrstr(char *haystack, int size, const char *needle)
  60  {
  61  	int loop = 0;
  62  
  63  	while (loop < (size-1)) {
  64  		if ((haystack[loop] == needle[0])&&
  65  		    (haystack[loop+1] == needle[1]))
  66  			return &haystack[loop];
  67  		loop++;
  68  	}
  69  	return NULL;
  70  }
  71  
  72  static bool cta_open(struct cgpu_info *cointerra)
  73  {
  74  	int err, amount, offset = 0;
  75  	char buf[CTA_MSG_SIZE];
  76  	cgtimer_t ts_start;
  77  	bool ret = false;
  78  
  79  	if (cointerra->usbinfo.nodev)
  80  		return false;
  81  
  82  	applog(LOG_INFO, "CTA_OPEN");
  83  
  84  	cta_gen_message(buf, CTA_SEND_RESET);
  85  	// set the initial difficulty
  86  	buf[CTA_RESET_TYPE] = CTA_RESET_INIT | CTA_RESET_DIFF;
  87  	buf[CTA_RESET_DIFF] = diff_to_bits(CTA_INIT_DIFF);
  88  	buf[CTA_RESET_LOAD] = opt_cta_load ? opt_cta_load : 255;
  89  	buf[CTA_RESET_PSLOAD] = opt_ps_load;
  90  
  91  	if (cointerra->usbinfo.nodev)
  92  		return ret;
  93  
  94  	err = usb_write(cointerra, buf, CTA_MSG_SIZE, &amount, C_CTA_WRITE);
  95  	if (err) {
  96  		applog(LOG_INFO, "Write error %d, wrote %d of %d", err, amount, CTA_MSG_SIZE);
  97  		return ret;
  98  	}
  99  
 100  	cgtimer_time(&ts_start);
 101  
 102  	/* Read from the device for up to 2 seconds discarding any data that
 103  	 * doesn't match a reset complete acknowledgement. */
 104  	while (42) {
 105  		cgtimer_t ts_now, ts_diff;
 106  		char *msg;
 107  
 108  		cgtimer_time(&ts_now);
 109  		cgtimer_sub(&ts_now, &ts_start, &ts_diff);
 110  		if (cgtimer_to_ms(&ts_diff) > 2000) {
 111  			applog(LOG_DEBUG, "%s %d: Timed out waiting for response to reset init",
 112  			       cointerra->drv->name, cointerra->device_id);
 113  			break;
 114  		}
 115  
 116  		if (cointerra->usbinfo.nodev)
 117  			break;
 118  
 119  		err = usb_read(cointerra, buf + offset, CTA_MSG_SIZE - offset, &amount, C_CTA_READ);
 120  		if (err && err != LIBUSB_ERROR_TIMEOUT) {
 121  			applog(LOG_INFO, "%s %d: Read error %d, read %d", cointerra->drv->name,
 122  			       cointerra->device_id, err, amount);
 123  			break;
 124  		}
 125  		if (!amount)
 126  			continue;
 127  
 128  		msg = mystrstr(buf, amount, cointerra_hdr);
 129  		if (!msg) {
 130  			/* Keep the last byte in case it's the first byte of
 131  			 * the 2 byte header. */
 132  			offset = 1;
 133  			memmove(buf, buf + amount - 1, offset);
 134  			continue;
 135  		}
 136  
 137  		if (msg > buf) {
 138  			/* length of message = offset for next usb_read after moving */
 139  			offset = CTA_MSG_SIZE - (msg - buf);
 140  			memmove(buf, msg, offset);
 141  			continue;
 142  		}
 143  
 144  		/* We have a full sized message starting with the header now */
 145  		if (cta_reset_init(buf)) {
 146  			/* We can't store any other data returned with this
 147  			 * reset since we have not allocated any memory for
 148  			 * a cointerra_info structure yet. */
 149  			applog(LOG_INFO, "%s %d: Successful reset init received",
 150  			       cointerra->drv->name, cointerra->device_id);
 151  			ret = true;
 152  			break;
 153  		}
 154  	}
 155  
 156  	return ret;
 157  }
 158  
 159  static void cta_clear_work(struct cgpu_info *cgpu)
 160  {
 161  	struct work *work, *tmp;
 162  
 163  	wr_lock(&cgpu->qlock);
 164  	HASH_ITER(hh, cgpu->queued_work, work, tmp) {
 165  		__work_completed(cgpu, work);
 166  		free_work(work);
 167  	}
 168  	wr_unlock(&cgpu->qlock);
 169  }
 170  
 171  static void cta_close(struct cgpu_info *cointerra)
 172  {
 173  	struct cointerra_info *info = cointerra->device_data;
 174  
 175  	/* Wait for read thread to die */
 176  	pthread_join(info->read_thr, NULL);
 177  
 178  	/* Open does the same reset init followed by response as is required to
 179  	 * close the device. */
 180  	if (!cta_open(cointerra)) {
 181  		applog(LOG_INFO, "%s %d: Reset on close failed", cointerra->drv->name,
 182  			cointerra->device_id);
 183  	}
 184  
 185  	mutex_destroy(&info->lock);
 186  	mutex_destroy(&info->sendlock);
 187  	/* Don't free info here to avoid trying to access dereferenced members
 188  	 * once a device is unplugged. */
 189  	cta_clear_work(cointerra);
 190  }
 191  
 192  static struct cgpu_info *cta_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
 193  {
 194  	struct cgpu_info *cointerra = usb_alloc_cgpu(&cointerra_drv, 1);
 195  	int tries = 0;
 196  
 197  	if (!usb_init(cointerra, dev, found))
 198  		goto fail;
 199  	applog(LOG_INFO, "%s %d: Found at %s", cointerra->drv->name,
 200  	       cointerra->device_id, cointerra->device_path);
 201  
 202  	while (!cta_open(cointerra) && !cointerra->usbinfo.nodev) {
 203  		if (tries++ > 3)
 204  			goto failed_open;
 205  		applog(LOG_INFO, "%s %d: Failed to open %d times, retrying", cointerra->drv->name,
 206  		       cointerra->device_id, tries);
 207  	}
 208  
 209  	if (!add_cgpu(cointerra))
 210  		goto fail_close;
 211  
 212  	update_usb_stats(cointerra);
 213  	applog(LOG_INFO, "%s %d: Successfully set up %s", cointerra->drv->name,
 214  	       cointerra->device_id, cointerra->device_path);
 215  	return cointerra;
 216  
 217  fail_close:
 218  	cta_close(cointerra);
 219  failed_open:
 220  	applog(LOG_INFO, "%s %d: Failed to initialise %s", cointerra->drv->name,
 221  	       cointerra->device_id, cointerra->device_path);
 222  fail:
 223  	usb_free_cgpu(cointerra);
 224  	return NULL;
 225  }
 226  
 227  static void cta_detect(bool __maybe_unused hotplug)
 228  {
 229  	usb_detect(&cointerra_drv, cta_detect_one);
 230  }
 231  
 232  /* This function will remove a work item from the hashtable if it matches the
 233   * id in work->subid and return a pointer to the work but it will not free the
 234   * work. It may return NULL if it cannot find matching work. */
 235  static struct work *take_work_by_id(struct cgpu_info *cgpu, uint16_t id)
 236  {
 237  	struct work *work, *tmp, *ret = NULL;
 238  
 239  	wr_lock(&cgpu->qlock);
 240  	HASH_ITER(hh, cgpu->queued_work, work, tmp) {
 241  		if (work->subid == id) {
 242  			ret = work;
 243  			break;
 244  		}
 245  	}
 246  	if (ret)
 247  		__work_completed(cgpu, ret);
 248  	wr_unlock(&cgpu->qlock);
 249  
 250  	return ret;
 251  }
 252  
 253  /* This function will look up a work item in the hashtable if it matches the
 254   * id in work->subid and return a cloned work item if it matches. It may return
 255   * NULL if it cannot find matching work. */
 256  static struct work *clone_work_by_id(struct cgpu_info *cgpu, uint16_t id)
 257  {
 258  	struct work *work, *tmp, *ret = NULL;
 259  
 260  	rd_lock(&cgpu->qlock);
 261  	HASH_ITER(hh, cgpu->queued_work, work, tmp) {
 262  		if (work->subid == id) {
 263  			ret = work;
 264  			break;
 265  		}
 266  	}
 267  	if (ret)
 268  		ret = copy_work(ret);
 269  	rd_unlock(&cgpu->qlock);
 270  
 271  	return ret;
 272  }
 273  
 274  static bool cta_send_msg(struct cgpu_info *cointerra, char *buf);
 275  
 276  static uint16_t hu16_from_msg(char *buf, int msg)
 277  {
 278  	return le16toh(*(uint16_t *)&buf[msg]);
 279  }
 280  
 281  static uint32_t hu32_from_msg(char *buf, int msg)
 282  {
 283  	return le32toh(*(uint32_t *)&buf[msg]);
 284  }
 285  
 286  static uint64_t hu64_from_msg(char *buf, int msg)
 287  {
 288  	return le64toh(*(uint64_t *)&buf[msg]);
 289  }
 290  
 291  static uint8_t u8_from_msg(char *buf, int msg)
 292  {
 293  	return *(uint8_t *)&buf[msg];
 294  }
 295  
 296  static void msg_from_hu16(char *buf, int msg, uint16_t val)
 297  {
 298  	*(uint16_t *)&buf[msg] = htole16(val);
 299  }
 300  
 301  static void cta_parse_reqwork(struct cgpu_info *cointerra, struct cointerra_info *info,
 302  			      char *buf)
 303  {
 304  	uint16_t retwork;
 305  
 306  	retwork = hu16_from_msg(buf, CTA_REQWORK_REQUESTS);
 307  	applog(LOG_DEBUG, "%s %d: Request work message for %u items received",
 308  	       cointerra->drv->name, cointerra->device_id, retwork);
 309  
 310  	mutex_lock(&info->lock);
 311  	info->requested = retwork;
 312  	/* Wake up the main scanwork loop since we need more
 313  		* work. */
 314  	pthread_cond_signal(&info->wake_cond);
 315  	mutex_unlock(&info->lock);
 316  }
 317  
 318  static void cta_parse_recvmatch(struct thr_info *thr, struct cgpu_info *cointerra,
 319  				struct cointerra_info *info, char *buf)
 320  {
 321  	uint32_t timestamp_offset, mcu_tag;
 322  	uint16_t retwork;
 323  	struct work *work;
 324  
 325  	/* No endian switch needs doing here since it's sent and returned as
 326  	 * the same 4 bytes */
 327  	retwork = *(uint16_t *)(&buf[CTA_DRIVER_TAG]);
 328  	mcu_tag = hu32_from_msg(buf, CTA_MCU_TAG);
 329  	applog(LOG_DEBUG, "%s %d: Match message for id 0x%04x MCU id 0x%08x received",
 330  	       cointerra->drv->name, cointerra->device_id, retwork, mcu_tag);
 331  
 332  	work = clone_work_by_id(cointerra, retwork);
 333  	if (likely(work)) {
 334  		uint8_t wdiffbits = u8_from_msg(buf, CTA_WORK_DIFFBITS);
 335  		uint32_t nonce = hu32_from_msg(buf, CTA_MATCH_NONCE);
 336  		unsigned char rhash[32];
 337  		char outhash[16];
 338  		double wdiff;
 339  		bool ret;
 340  
 341  		timestamp_offset = hu32_from_msg(buf, CTA_MATCH_NOFFSET);
 342  		if (timestamp_offset) {
 343  			struct work *base_work = work;
 344  
 345  			work = copy_work_noffset(base_work, timestamp_offset);
 346  			free_work(base_work);
 347  		}
 348  
 349  		/* Test against the difficulty we asked for along with the work */
 350  		wdiff = bits_to_diff(wdiffbits);
 351  		ret = test_nonce_diff(work, nonce, wdiff);
 352  
 353  		if (opt_debug) {
 354  			/* Debugging, remove me */
 355  			swab256(rhash, work->hash);
 356  			__bin2hex(outhash, rhash, 8);
 357  			applog(LOG_WARNING, "submit work %s 0x%04x 0x%08x %d 0x%08x",
 358  			       outhash, retwork, mcu_tag, timestamp_offset, nonce);
 359  		}
 360  
 361  		if (likely(ret)) {
 362  			uint8_t asic, core, pipe, coreno;
 363  			int pipeno, bitchar, bitbit;
 364  			uint64_t hashes;
 365  
 366  			asic = u8_from_msg(buf, CTA_MCU_ASIC);
 367  			core = u8_from_msg(buf, CTA_MCU_CORE);
 368  			pipe = u8_from_msg(buf, CTA_MCU_PIPE);
 369  			pipeno = asic * 512 + core * 128 + pipe;
 370  			coreno = asic * 4 + core;
 371  			if (unlikely(asic > 1 || core > 3 || pipe > 127 || pipeno > 1023)) {
 372  				applog(LOG_WARNING, "%s %d: MCU invalid pipe asic %d core %d pipe %d",
 373  				       cointerra->drv->name, cointerra->device_id, asic, core, pipe);
 374  				coreno = 0;
 375  			} else {
 376  				info->last_pipe_nonce[pipeno] = time(NULL);
 377  				bitchar = pipeno / 8;
 378  				bitbit = pipeno % 8;
 379  				info->pipe_bitmap[bitchar] |= 0x80 >> bitbit;
 380  			}
 381  
 382  			applog(LOG_DEBUG, "%s %d: Submitting tested work job_id %s work_id %u",
 383  			       cointerra->drv->name, cointerra->device_id, work->job_id, work->subid);
 384  			ret = submit_tested_work(thr, work);
 385  
 386  			hashes = (uint64_t)wdiff * 0x100000000ull;
 387  			mutex_lock(&info->lock);
 388  			info->share_hashes += hashes;
 389  			info->tot_core_hashes[coreno] += hashes;
 390  			info->hashes += nonce;
 391  			mutex_unlock(&info->lock);
 392  		} else {
 393  			char sendbuf[CTA_MSG_SIZE];
 394  			uint8_t asic, core, coreno;
 395  			asic = u8_from_msg(buf, CTA_MCU_ASIC);
 396  			core = u8_from_msg(buf, CTA_MCU_CORE);
 397  			coreno = asic * 4 + core;
 398  			inc_hw_errors(thr);
 399  
 400  			applog(LOG_WARNING, "%s %d: Notify bad match work",
 401  			       cointerra->drv->name, cointerra->device_id);
 402  			if (coreno < CTA_CORES)
 403  				info->fmatch_errors[coreno]++;
 404  			if (opt_debug) {
 405  				uint64_t sdiff = share_diff(work);
 406  				unsigned char midstate[32], wdata[12];
 407  				char hexmidstate[68], hexwdata[28];
 408  				uint16_t wid;
 409  
 410  				memcpy(&wid, &info->work_id, 2);
 411  				flip32(midstate, work->midstate);
 412  				__bin2hex(hexmidstate, midstate, 32);
 413  				flip12(wdata, &work->data[64]);
 414  				__bin2hex(hexwdata, wdata, 12);
 415  				applog(LOG_DEBUG, "False match sent: work id %u midstate %s  blkhdr %s",
 416  				       wid, hexmidstate, hexwdata);
 417  				applog(LOG_DEBUG, "False match reports: work id 0x%04x MCU id 0x%08x work diff %.1f",
 418  				       retwork, mcu_tag, wdiff);
 419  				applog(LOG_DEBUG, "False match tested: nonce 0x%08x noffset %d %s",
 420  				       nonce, timestamp_offset, outhash);
 421  				applog(LOG_DEBUG, "False match devdiff set to %.1f share diff calc %"PRIu64,
 422  				       work->device_diff, sdiff);
 423  			}
 424  
 425  			/* Tell the device we got a false match */
 426  			cta_gen_message(sendbuf, CTA_SEND_FMATCH);
 427  			memcpy(sendbuf + 3, buf + 3, CTA_MSG_SIZE - 3);
 428  			cta_send_msg(cointerra, sendbuf);
 429  		}
 430  		free_work(work);
 431  	} else {
 432  		applog(LOG_WARNING, "%s %d: Matching work id 0x%X %d not found", cointerra->drv->name,
 433  		       cointerra->device_id, retwork, __LINE__);
 434  		inc_hw_errors(thr);
 435  
 436  		mutex_lock(&info->lock);
 437  		info->no_matching_work++;
 438  		mutex_unlock(&info->lock);
 439  	}
 440  }
 441  
 442  static void cta_parse_wdone(struct thr_info *thr, struct cgpu_info *cointerra,
 443  			    struct cointerra_info *info, char *buf)
 444  {
 445  	uint16_t retwork = *(uint16_t *)(&buf[CTA_DRIVER_TAG]);
 446  	struct work *work = take_work_by_id(cointerra, retwork);
 447  	uint64_t hashes;
 448  
 449  	if (likely(work)) {
 450  		free_work(work);
 451  		applog(LOG_DEBUG, "%s %d: Done work found id 0x%X %d",
 452  		       cointerra->drv->name, cointerra->device_id, retwork, __LINE__);
 453  	} else {
 454  		applog(LOG_WARNING, "%s %d: Done work not found id 0x%X %d",
 455  		       cointerra->drv->name, cointerra->device_id, retwork, __LINE__);
 456  		inc_hw_errors(thr);
 457  	}
 458  
 459  	/* Removing hashes from work done message */
 460  	hashes = hu64_from_msg(buf, CTA_WDONE_NONCES);
 461  	if (unlikely(hashes > (61 * 0x100000000ull))) {
 462  		applog(LOG_INFO, "%s Invalid hash returned %"PRIu64"x %"PRIu64"x %"PRIu64"X",
 463  		       __func__, info->hashes, hashes, hashes);
 464  		hashes = 0;
 465  	}
 466  
 467  	mutex_lock(&info->lock);
 468  	info->hashes += hashes;
 469  	mutex_unlock(&info->lock);
 470  }
 471  
 472  static void u16array_from_msg(uint16_t *u16, int entries, int var, char *buf)
 473  {
 474  	int i, j;
 475  
 476  	for (i = 0, j = 0; i < entries; i++, j += sizeof(uint16_t))
 477  		u16[i] = hu16_from_msg(buf, var + j);
 478  }
 479  
 480  static void cta_parse_statread(struct cgpu_info *cointerra, struct cointerra_info *info,
 481  			       char *buf)
 482  {
 483  	float max_temp = 0;
 484  	int i;
 485  
 486  	mutex_lock(&info->lock);
 487  	u16array_from_msg(info->coretemp, CTA_CORES, CTA_STAT_CORETEMPS, buf);
 488  	info->ambtemp_low = hu16_from_msg(buf, CTA_STAT_AMBTEMP_LOW);
 489  	info->ambtemp_avg = hu16_from_msg(buf, CTA_STAT_AMBTEMP_AVG);
 490  	info->ambtemp_high = hu16_from_msg(buf, CTA_STAT_AMBTEMP_HIGH);
 491  	u16array_from_msg(info->pump_tachs, CTA_PUMPS, CTA_STAT_PUMP_TACHS, buf);
 492  	u16array_from_msg(info->fan_tachs, CTA_FANS, CTA_STAT_FAN_TACHS, buf);
 493  	u16array_from_msg(info->corevolts, CTA_CORES, CTA_STAT_CORE_VOLTS, buf);
 494  	info->volts33 = hu16_from_msg(buf, CTA_STAT_VOLTS33);
 495  	info->volts12 = hu16_from_msg(buf, CTA_STAT_VOLTS12);
 496  	info->inactive = hu16_from_msg(buf, CTA_STAT_INACTIVE);
 497  	info->active = hu16_from_msg(buf, CTA_STAT_ACTIVE);
 498  	mutex_unlock(&info->lock);
 499  
 500  	for (i = 0; i < CTA_CORES; i++) {
 501  		if (info->coretemp[i] > max_temp)
 502  			max_temp = info->coretemp[i];
 503  	}
 504  	max_temp /= 100.0;
 505  	/* Store the max temperature in the cgpu struct as an exponentially
 506  	 * changing value. */
 507  	cointerra->temp = cointerra->temp * 0.63 + max_temp * 0.37;
 508  }
 509  
 510  static void u8array_from_msg(uint8_t *u8, int entries, int var, char *buf)
 511  {
 512  	int i;
 513  
 514  	for (i = 0; i < entries; i++)
 515  		u8[i] = u8_from_msg(buf, var + i);
 516  }
 517  
 518  static void cta_parse_statset(struct cointerra_info *info, char *buf)
 519  {
 520  	mutex_lock(&info->lock);
 521  	u8array_from_msg(info->coreperf, CTA_CORES, CTA_STAT_PERFMODE, buf);
 522  	u8array_from_msg(info->fanspeed, CTA_FANS, CTA_STAT_FANSPEEDS, buf);
 523  	info->dies_active = u8_from_msg(buf, CTA_STAT_DIES_ACTIVE);
 524  	u8array_from_msg(info->pipes_enabled, CTA_CORES, CTA_STAT_PIPES_ENABLED, buf);
 525  	u16array_from_msg(info->corefreqs, CTA_CORES, CTA_STAT_CORE_FREQS, buf);
 526  	info->uptime = hu32_from_msg(buf,CTA_STAT_UPTIME);
 527  	mutex_unlock(&info->lock);
 528  }
 529  
 530  static void cta_parse_irstat(struct cointerra_info *info, char *buf)
 531  {
 532  	uint8_t channel = u8_from_msg(buf,CTA_IRSTAT_CHANNEL);
 533  
 534  	if (channel >= CTA_CORES)
 535  		return;
 536  
 537  	mutex_lock(&info->lock);
 538  	info->irstat_vin[channel] = hu16_from_msg(buf,CTA_IRSTAT_VIN);
 539  	info->irstat_iin[channel] = hu16_from_msg(buf,CTA_IRSTAT_IIN);
 540  	info->irstat_vout[channel] = hu16_from_msg(buf,CTA_IRSTAT_VOUT);
 541  	info->irstat_iout[channel] = hu16_from_msg(buf,CTA_IRSTAT_IOUT);
 542  	info->irstat_temp1[channel] = hu16_from_msg(buf,CTA_IRSTAT_TEMP1);
 543  	info->irstat_temp2[channel] = hu16_from_msg(buf,CTA_IRSTAT_TEMP2);
 544  	info->irstat_pout[channel] = hu16_from_msg(buf,CTA_IRSTAT_POUT);
 545  	info->irstat_pin[channel] = hu16_from_msg(buf,CTA_IRSTAT_PIN);
 546  	info->irstat_efficiency[channel] = hu16_from_msg(buf,CTA_IRSTAT_EFF);
 547  	info->irstat_status[channel] = hu16_from_msg(buf,CTA_IRSTAT_STATUS);
 548  	mutex_unlock(&info->lock);
 549  }
 550  
 551  static void cta_parse_info(struct cgpu_info *cointerra, struct cointerra_info *info,
 552  			   char *buf)
 553  {
 554  	mutex_lock(&info->lock);
 555  	info->hwrev = hu64_from_msg(buf, CTA_INFO_HWREV);
 556  	info->serial = hu32_from_msg(buf, CTA_INFO_SERNO);
 557  	info->asics = u8_from_msg(buf, CTA_INFO_NUMASICS);
 558  	info->dies = u8_from_msg(buf, CTA_INFO_NUMDIES);
 559  	info->cores = hu16_from_msg(buf, CTA_INFO_NUMCORES);
 560  	info->board_number = u8_from_msg(buf, CTA_INFO_BOARDNUMBER);
 561  	info->fwrev[0] = u8_from_msg(buf, CTA_INFO_FWREV_MAJ);
 562  	info->fwrev[1] = u8_from_msg(buf, CTA_INFO_FWREV_MIN);
 563  	info->fwrev[2] = u8_from_msg(buf, CTA_INFO_FWREV_MIC);
 564  	info->fw_year = hu16_from_msg(buf, CTA_INFO_FWDATE_YEAR);
 565  	info->fw_month = u8_from_msg(buf, CTA_INFO_FWDATE_MONTH);
 566  	info->fw_day = u8_from_msg(buf, CTA_INFO_FWDATE_DAY);
 567  	info->init_diffbits = u8_from_msg(buf, CTA_INFO_INITDIFFBITS);
 568  	info->min_diffbits = u8_from_msg(buf, CTA_INFO_MINDIFFBITS);
 569  	info->max_diffbits = u8_from_msg(buf, CTA_INFO_MAXDIFFBITS);
 570  	mutex_unlock(&info->lock);
 571  
 572  	if (!cointerra->unique_id) {
 573  		uint32_t b32 = htobe32(info->serial);
 574  
 575  		cointerra->unique_id = bin2hex((unsigned char *)&b32, 4);
 576  	}
 577  }
 578  
 579  static void cta_parse_rdone(struct cgpu_info *cointerra, struct cointerra_info *info,
 580  			    char *buf)
 581  {
 582  	uint8_t reset_type, diffbits;
 583  	uint64_t wdone;
 584  
 585  	reset_type = buf[CTA_RESET_TYPE];
 586  	diffbits = buf[CTA_RESET_DIFF];
 587  	wdone = hu64_from_msg(buf, CTA_WDONE_NONCES);
 588  
 589  	if (wdone) {
 590  		applog(LOG_INFO, "%s %d: Reset done type %u message %u diffbits %"PRIu64" done received",
 591  			cointerra->drv->name, cointerra->device_id, reset_type, diffbits, wdone);
 592  
 593  		mutex_lock(&info->lock);
 594  		info->hashes += wdone;
 595  		mutex_unlock(&info->lock);
 596  	}
 597  
 598  	/* Note that the cgsem that is posted here must not be waited on while
 599  	 * holding the info->lock to not get into a livelock since this
 600  	 * function also grabs the lock first and it's always best to not sleep
 601  	 * while holding a lock. */
 602  	if (reset_type == CTA_RESET_NEW) {
 603  		cta_clear_work(cointerra);
 604  		/* Tell reset sender that the reset is complete
 605  			* and it may resume. */
 606  		cgsem_post(&info->reset_sem);
 607  	}
 608  }
 609  
 610  static void cta_zero_stats(struct cgpu_info *cointerra);
 611  
 612  static void cta_parse_debug(struct cointerra_info *info, char *buf)
 613  {
 614  	mutex_lock(&info->lock);
 615  
 616  	info->tot_underruns = hu16_from_msg(buf, CTA_STAT_UNDERRUNS);
 617  	u16array_from_msg(info->tot_hw_errors, CTA_CORES, CTA_STAT_HW_ERRORS, buf);
 618  	info->tot_hashes = hu64_from_msg(buf, CTA_STAT_HASHES);
 619  	info->tot_flushed_hashes = hu64_from_msg(buf, CTA_STAT_FLUSHED_HASHES);
 620  	info->autovoltage = u8_from_msg(buf, CTA_STAT_AUTOVOLTAGE);
 621  	info->current_ps_percent = u8_from_msg(buf, CTA_STAT_POWER_PERCENT);
 622  	info->power_used = hu16_from_msg(buf,CTA_STAT_POWER_USED);
 623  	info->power_voltage = hu16_from_msg(buf,CTA_STAT_VOLTAGE);
 624  	info->ipower_used = hu16_from_msg(buf,CTA_STAT_IPOWER_USED);
 625  	info->ipower_voltage = hu16_from_msg(buf,CTA_STAT_IVOLTAGE);
 626  	info->power_temps[0] = hu16_from_msg(buf,CTA_STAT_PS_TEMP1);
 627  	info->power_temps[1] = hu16_from_msg(buf,CTA_STAT_PS_TEMP2);
 628  
 629  	mutex_unlock(&info->lock);
 630  
 631  	/* Autovoltage is positive only once at startup and eventually drops
 632  	 * to zero. After that time we reset the stats since they're unreliable
 633  	 * till then. */
 634  	if (unlikely(!info->autovoltage_complete && !info->autovoltage)) {
 635  		struct cgpu_info *cointerra = info->thr->cgpu;
 636  
 637  		info->autovoltage_complete = true;
 638  		cgtime(&cointerra->dev_start_tv);
 639  		cta_zero_stats(cointerra);
 640  		cointerra->total_mhashes = 0;
 641  		cointerra->accepted = 0;
 642  		cointerra->rejected = 0;
 643  		cointerra->hw_errors = 0;
 644  		cointerra->utility = 0.0;
 645  		cointerra->last_share_pool_time = 0;
 646  		cointerra->diff1 = 0;
 647  		cointerra->diff_accepted = 0;
 648  		cointerra->diff_rejected = 0;
 649  		cointerra->last_share_diff = 0;
 650  	}
 651  }
 652  
 653  static int verify_checksum(char *buf)
 654  {
 655  	unsigned char checksum = 0;
 656  	unsigned char i;
 657  
 658  	for (i = 0; i < 63; i++)
 659  		checksum += buf[i];
 660  
 661  	return (checksum == buf[63]);
 662  }
 663  
 664  static void cta_parse_msg(struct thr_info *thr, struct cgpu_info *cointerra,
 665  			  struct cointerra_info *info, char *buf)
 666  {
 667  		if ((buf[CTA_MSG_TYPE] != CTA_RECV_MATCH)&&
 668  		    (buf[CTA_MSG_TYPE] != CTA_RECV_WDONE)) {
 669  			if (unlikely(verify_checksum(buf) == 0)) {
 670  				inc_hw_errors(thr);
 671  				applog(LOG_INFO, "%s %d: checksum bad",cointerra->drv->name,cointerra->device_id);
 672  			}
 673  		}
 674  
 675  	switch (buf[CTA_MSG_TYPE]) {
 676  		default:
 677  		case CTA_RECV_UNUSED:
 678  			applog(LOG_INFO, "%s %d: Unidentified message type %u",
 679  			       cointerra->drv->name, cointerra->device_id, buf[CTA_MSG_TYPE]);
 680  			break;
 681  		case CTA_RECV_REQWORK:
 682  			cta_parse_reqwork(cointerra, info, buf);
 683  			break;
 684  		case CTA_RECV_MATCH:
 685  			cta_parse_recvmatch(thr, cointerra, info, buf);
 686  			break;
 687  		case CTA_RECV_WDONE:
 688  			applog(LOG_DEBUG, "%s %d: Work done message received",
 689  			       cointerra->drv->name, cointerra->device_id);
 690  			cta_parse_wdone(thr, cointerra, info, buf);
 691  			break;
 692  		case CTA_RECV_STATREAD:
 693  			applog(LOG_DEBUG, "%s %d: Status readings message received",
 694  			       cointerra->drv->name, cointerra->device_id);
 695  			cta_parse_statread(cointerra, info, buf);
 696  			break;
 697  		case CTA_RECV_STATSET:
 698  			applog(LOG_DEBUG, "%s %d: Status settings message received",
 699  			       cointerra->drv->name, cointerra->device_id);
 700  			cta_parse_statset(info, buf);
 701  			break;
 702  		case CTA_RECV_INFO:
 703  			applog(LOG_DEBUG, "%s %d: Info message received",
 704  			       cointerra->drv->name, cointerra->device_id);
 705  			cta_parse_info(cointerra, info, buf);
 706  			break;
 707  		case CTA_RECV_MSG:
 708  			applog(LOG_NOTICE, "%s %d: MSG: %s",
 709  			       cointerra->drv->name, cointerra->device_id, &buf[CTA_MSG_RECVD]);
 710  			break;
 711  		case CTA_RECV_RDONE:
 712  			cta_parse_rdone(cointerra, info, buf);
 713  			break;
 714  		case CTA_RECV_STATDEBUG:
 715  			cta_parse_debug(info, buf);
 716  			break;
 717  		case CTA_RECV_IRSTAT:
 718  			cta_parse_irstat(info, buf);
 719  			break;
 720  	}
 721  }
 722  
 723  static void *cta_recv_thread(void *arg)
 724  {
 725  	struct thr_info *thr = (struct thr_info *)arg;
 726  	struct cgpu_info *cointerra = thr->cgpu;
 727  	struct cointerra_info *info = cointerra->device_data;
 728  	char threadname[24];
 729  	int offset = 0;
 730  
 731  	snprintf(threadname, 24, "cta_recv/%d", cointerra->device_id);
 732  	RenameThread(threadname);
 733  
 734  	while (likely(!cointerra->shutdown)) {
 735  		char buf[CTA_READBUF_SIZE];
 736  		int amount, err;
 737  
 738  		if (unlikely(cointerra->usbinfo.nodev)) {
 739  			applog(LOG_DEBUG, "%s %d: Device disappeared, disabling recv thread",
 740  			       cointerra->drv->name, cointerra->device_id);
 741  			break;
 742  		}
 743  
 744  		err = usb_read(cointerra, buf + offset, CTA_MSG_SIZE, &amount, C_CTA_READ);
 745  		if (err && err != LIBUSB_ERROR_TIMEOUT) {
 746  			applog(LOG_ERR, "%s %d: Read error %d, read %d", cointerra->drv->name,
 747  			       cointerra->device_id, err, amount);
 748  			break;
 749  		}
 750  		offset += amount;
 751  
 752  		while (offset >= CTA_MSG_SIZE) {
 753  			char *msg = mystrstr(buf, offset, cointerra_hdr);
 754  			int begin;
 755  
 756  			if (unlikely(!msg)) {
 757  				applog(LOG_WARNING, "%s %d: No message header found, discarding buffer",
 758  				       cointerra->drv->name, cointerra->device_id);
 759  				inc_hw_errors(thr);
 760  				/* Save the last byte in case it's the fist
 761  				 * byte of a header. */
 762  				begin = CTA_MSG_SIZE - 1;
 763  				offset -= begin;
 764  				memmove(buf, buf + begin, offset);
 765  				continue;
 766  			}
 767  
 768  			if (unlikely(msg != buf)) {
 769  				begin = msg - buf;
 770  				applog(LOG_WARNING, "%s %d: Reads out of sync, discarding %d bytes",
 771  				       cointerra->drv->name, cointerra->device_id, begin);
 772  				inc_hw_errors(thr);
 773  				offset -= begin;
 774  				memmove(buf, msg, offset);
 775  				if (offset < CTA_MSG_SIZE)
 776  					break;
 777  			}
 778  
 779  			/* We have enough buffer for a full message, parse now */
 780  			cta_parse_msg(thr, cointerra, info, msg);
 781  			offset -= CTA_MSG_SIZE;
 782  			if (offset > 0)
 783  				memmove(buf, buf + CTA_MSG_SIZE, offset);
 784  		}
 785  	}
 786  
 787  	return NULL;
 788  }
 789  
 790  static bool cta_send_msg(struct cgpu_info *cointerra, char *buf)
 791  {
 792  	struct cointerra_info *info = cointerra->device_data;
 793  	int amount, err;
 794  
 795  	if (unlikely(cointerra->usbinfo.nodev))
 796  		return false;
 797  
 798  	/* Serialise usb writes to prevent overlap in case multiple threads
 799  	 * send messages */
 800  	mutex_lock(&info->sendlock);
 801  	err = usb_write(cointerra, buf, CTA_MSG_SIZE, &amount, C_CTA_WRITE);
 802  	mutex_unlock(&info->sendlock);
 803  
 804  	if (unlikely(err || amount != CTA_MSG_SIZE)) {
 805  		applog(LOG_ERR, "%s %d: Write error %d, wrote %d of %d", cointerra->drv->name,
 806  		       cointerra->device_id, err, amount, CTA_MSG_SIZE);
 807  		return false;
 808  	}
 809  	return true;
 810  }
 811  
 812  static bool cta_prepare(struct thr_info *thr)
 813  {
 814  	struct cgpu_info *cointerra = thr->cgpu;
 815  	struct cointerra_info *info = calloc(sizeof(struct cointerra_info), 1);
 816  	char buf[CTA_MSG_SIZE];
 817  
 818  	if (unlikely(cointerra->usbinfo.nodev))
 819  		return false;
 820  
 821  	if (unlikely(!info))
 822  		quit(1, "Failed to calloc info in cta_detect_one");
 823  	cointerra->device_data = info;
 824  	/* Nominally set a requested value when starting, preempting the need
 825  	 * for a req-work message. */
 826  	info->requested = CTA_MAX_QUEUE;
 827  
 828  	info->thr = thr;
 829  	mutex_init(&info->lock);
 830  	mutex_init(&info->sendlock);
 831  	if (unlikely(pthread_cond_init(&info->wake_cond, NULL)))
 832  		quit(1, "Failed to create cta pthread cond");
 833  	cgsem_init(&info->reset_sem);
 834  	if (pthread_create(&info->read_thr, NULL, cta_recv_thread, (void *)thr))
 835  		quit(1, "Failed to create cta_recv_thread");
 836  
 837  	/* Request a single status setting message */
 838  	cta_gen_message(buf, CTA_SEND_REQUEST);
 839  	msg_from_hu16(buf, CTA_REQ_MSGTYPE, CTA_RECV_STATSET);
 840  	msg_from_hu16(buf, CTA_REQ_INTERVAL, 0);
 841  	if (!cta_send_msg(cointerra, buf))
 842  		return false;
 843  
 844  	/* Request status debug messages every 60 seconds */
 845  	cta_gen_message(buf, CTA_SEND_REQUEST);
 846  	msg_from_hu16(buf, CTA_REQ_MSGTYPE, CTA_RECV_STATDEBUG);
 847  	msg_from_hu16(buf, CTA_REQ_INTERVAL, 6000);
 848  	if (!cta_send_msg(cointerra, buf))
 849  		return false;
 850  
 851  	cgtime(&info->core_hash_start);
 852  
 853  	return true;
 854  }
 855  
 856  static void cta_send_reset(struct cgpu_info *cointerra, struct cointerra_info *info,
 857  			   uint8_t reset_type, uint8_t diffbits);
 858  static void cta_flush_work(struct cgpu_info *cointerra);
 859  
 860  /* *_fill and *_scanwork are serialised wrt to each other */
 861  static bool cta_fill(struct cgpu_info *cointerra)
 862  {
 863  	struct cointerra_info *info = cointerra->device_data;
 864  	bool ret = true;
 865  	char buf[CTA_MSG_SIZE];
 866  	struct work *work = NULL;
 867  	unsigned short nroll_limit;
 868  	uint32_t swab[8];
 869  	uint8_t diffbits;
 870  
 871  	//applog(LOG_WARNING, "%s %d: cta_fill %d", cointerra->drv->name, cointerra->device_id,__LINE__);
 872  
 873  	if (unlikely(info->thr->work_restart))
 874  		cta_flush_work(cointerra);
 875  
 876  	mutex_lock(&info->lock);
 877  	if (!info->requested)
 878  		goto out_unlock;
 879  	work = get_queued(cointerra);
 880  	if (unlikely(!work)) {
 881  		ret = false;
 882  		goto out_unlock;
 883  	}
 884  	if (--info->requested > 0)
 885  		ret = false;
 886  
 887  	/* It does not matter what endian this uint16_t is since it will be
 888  	 * the same value on sending to the MC as returning in match/done. This
 889  	 * will automatically wrap as a uint16_t. It cannot be zero for the MCU
 890  	 * though. */
 891  	if (unlikely(++info->work_id == 0))
 892  		info->work_id = 1;
 893  	work->subid = info->work_id;
 894  
 895  	diffbits = diff_to_bits(work->device_diff);
 896  
 897  	cta_gen_message(buf, CTA_SEND_WORK);
 898  
 899   	memcpy(buf + CTA_DRIVER_TAG, &info->work_id, 2);
 900  
 901  	flip32(swab, work->midstate);
 902  	memcpy(buf + CTA_WORK_MIDSTATE, swab, 32);
 903  
 904  	flip12(swab, &work->data[64]);
 905  	memcpy(buf + CTA_WORK_DATA, swab, 12);
 906  
 907  	nroll_limit = htole16(work->drv_rolllimit);
 908  	memcpy(buf + CTA_WORK_NROLL, &nroll_limit, 2);
 909  
 910  	memcpy(buf + CTA_WORK_DIFFBITS, &diffbits, 1);
 911  
 912  out_unlock:
 913  	mutex_unlock(&info->lock);
 914  
 915  	if (work) {
 916  		cgtime(&work->tv_work_start);
 917  		applog(LOG_DEBUG, "%s %d: Sending work job_id %s work_id %u", cointerra->drv->name,
 918  		       cointerra->device_id, work->job_id, work->subid);
 919  		if (unlikely(!cta_send_msg(cointerra, buf))) {
 920  			work_completed(cointerra, work);
 921  			applog(LOG_INFO, "%s %d: Failed to send work",
 922  			       cointerra->drv->name, cointerra->device_id);
 923  			/* The device will fail after this */
 924  		}
 925  	}
 926  
 927  	return ret;
 928  }
 929  
 930  static void cta_send_reset(struct cgpu_info *cointerra, struct cointerra_info *info,
 931  			   uint8_t reset_type, uint8_t diffbits)
 932  {
 933  	char buf[CTA_MSG_SIZE];
 934  	int ret, retries = 0;
 935  
 936  	/* Clear any accumulated messages in case we've gotten out of sync. */
 937  	cgsem_reset(&info->reset_sem);
 938  resend:
 939  	cta_gen_message(buf, CTA_SEND_RESET);
 940  
 941  	buf[CTA_RESET_TYPE] = reset_type;
 942  	buf[CTA_RESET_LOAD] = opt_cta_load ? opt_cta_load : 255;
 943  	buf[CTA_RESET_PSLOAD] = opt_ps_load;
 944  
 945  	applog(LOG_INFO, "%s %d: Sending Reset type %u with diffbits %u", cointerra->drv->name,
 946  	       cointerra->device_id, reset_type, diffbits);
 947  	cta_send_msg(cointerra, buf);
 948  
 949  	/* Wait for read thread to parse a reset message and signal us we may
 950  	 * return to submitting other messages. Use a timeout in case we have
 951  	 * a problem and the reset done message never returns. */
 952  	if (reset_type == CTA_RESET_NEW) {
 953  		ret = cgsem_mswait(&info->reset_sem, CTA_RESET_TIMEOUT);
 954  		if (ret) {
 955  			if (++retries < 5) {
 956  				applog(LOG_INFO, "%s %d: Timed out waiting for reset done msg, retrying",
 957  				       cointerra->drv->name, cointerra->device_id);
 958  				goto resend;
 959  			}
 960  			applog(LOG_WARNING, "%s %d: Timed out waiting for reset done msg",
 961  			       cointerra->drv->name, cointerra->device_id);
 962  		}
 963  		/* Good place to flush any work we have */
 964  		flush_queue(cointerra);
 965  	}
 966  }
 967  
 968  static void cta_flush_work(struct cgpu_info *cointerra)
 969  {
 970  	struct cointerra_info *info = cointerra->device_data;
 971  
 972  	applog(LOG_INFO, "%s %d: cta_flush_work %d", cointerra->drv->name, cointerra->device_id,
 973  	       __LINE__);
 974  	cta_send_reset(cointerra, info, CTA_RESET_NEW, 0);
 975  	info->thr->work_restart = false;
 976  }
 977  
 978  static void cta_update_work(struct cgpu_info *cointerra)
 979  {
 980  	struct cointerra_info *info = cointerra->device_data;
 981  
 982  	applog(LOG_INFO, "%s %d: Update work", cointerra->drv->name, cointerra->device_id);
 983  	cta_send_reset(cointerra, info, CTA_RESET_UPDATE, 0);
 984  }
 985  
 986  static void cta_zero_corehashes(struct cointerra_info *info)
 987  {
 988  	int i;
 989  
 990  	for (i = 0; i < CTA_CORES; i++)
 991  		info->tot_core_hashes[i] = 0;
 992  	cgtime(&info->core_hash_start);
 993  }
 994  
 995  /* Send per core hashrate calculations at regular intervals ~every 5 minutes */
 996  static void cta_send_corehashes(struct cgpu_info *cointerra, struct cointerra_info *info,
 997  				double corehash_time)
 998  {
 999  	uint16_t core_ghs[CTA_CORES];
1000  	double k[CTA_CORES];
1001  	char buf[CTA_MSG_SIZE];
1002  	int i, offset;
1003  
1004  	for (i = 0; i < CTA_CORES; i++) {
1005  		k[i] = (double)info->tot_core_hashes[i];
1006  #if 0
1007  		k[i] /= ((double)32 * (double)0x100000000ull);
1008  		k[i] = sqrt(k[i]) + 1;
1009  		k[i] *= k[i];
1010  		k[i] = k[i] * 32 * ((double)0x100000000ull );
1011  #endif
1012  		k[i] /= ((double)1000000000 * corehash_time);
1013  		core_ghs[i] = k[i];
1014  	}
1015  	cta_gen_message(buf, CTA_SEND_COREHASHRATE);
1016  	offset = CTA_CORE_HASHRATES;
1017  	for (i = 0; i < CTA_CORES; i++) {
1018  		msg_from_hu16(buf, offset, core_ghs[i]);
1019  		offset += 2; // uint16_t
1020  	}
1021  	cta_send_msg(cointerra, buf);
1022  }
1023  
1024  static int64_t cta_scanwork(struct thr_info *thr)
1025  {
1026  	struct cgpu_info *cointerra = thr->cgpu;
1027  	struct cointerra_info *info = cointerra->device_data;
1028  	double corehash_time;
1029  	struct timeval now;
1030  	uint32_t runtime;
1031  	int64_t hashes;
1032  
1033  	applog(LOG_DEBUG, "%s %d: cta_scanwork %d", cointerra->drv->name, cointerra->device_id,__LINE__);
1034  
1035  	if (unlikely(cointerra->usbinfo.nodev)) {
1036  		hashes = -1;
1037  		goto out;
1038  	}
1039  
1040  	cgtime(&now);
1041  
1042  	if (unlikely(thr->work_restart)) {
1043  		applog(LOG_INFO, "%s %d: Flush work line %d",
1044  		     cointerra->drv->name, cointerra->device_id,__LINE__);
1045  		cta_flush_work(cointerra);
1046  	} else {
1047  		struct timespec abstime, tsdiff = {0, 500000000};
1048  		time_t now_t;
1049  		int i;
1050  
1051  		timeval_to_spec(&abstime, &now);
1052  		timeraddspec(&abstime, &tsdiff);
1053  
1054  		/* Discard work that was started more than 5 minutes ago as
1055  		 * a safety precaution backup in case the hardware failed to
1056  		 * return a work done message for some work items. */
1057  		age_queued_work(cointerra, 300.0);
1058  
1059  		/* Each core should be 1.7MH so at max diff of 32 should
1060  		 * average a share every ~80 seconds.Use this opportunity to
1061  		 * unset the bits in any pipes that have not returned a valid
1062  		 * nonce for over 30 full nonce ranges or 2400s. */
1063  		now_t = time(NULL);
1064  		for (i = 0; i < 1024; i++) {
1065  			if (unlikely(now_t > info->last_pipe_nonce[i] + 2400)) {
1066  				int bitchar = i / 8, bitbit = i % 8;
1067  
1068  				info->pipe_bitmap[bitchar] &= ~(0x80 >> bitbit);
1069  			}
1070  		}
1071  
1072  		/* Sleep for up to 0.5 seconds, waking if we need work or
1073  		 * have received a restart message. */
1074  		mutex_lock(&info->lock);
1075  		pthread_cond_timedwait(&info->wake_cond, &info->lock, &abstime);
1076  		mutex_unlock(&info->lock);
1077  
1078  		if (thr->work_restart) {
1079  			applog(LOG_INFO, "%s %d: Flush work line %d",
1080  			       cointerra->drv->name, cointerra->device_id,__LINE__);
1081  			cta_flush_work(cointerra);
1082  		}
1083  	}
1084  
1085  	corehash_time = tdiff(&now, &info->core_hash_start);
1086  	if (corehash_time > 300) {
1087  		cta_send_corehashes(cointerra, info, corehash_time);
1088  		cta_zero_corehashes(info);
1089  	}
1090  
1091  	mutex_lock(&info->lock);
1092  	hashes = info->share_hashes;
1093  	info->tot_share_hashes += info->share_hashes;
1094  	info->tot_calc_hashes += info->hashes;
1095  	runtime = cgpu_runtime(thr->cgpu);
1096  	runtime /= 30;
1097  	info->old_hashes[runtime % 32] = info->tot_calc_hashes;
1098  	info->hashes = info->share_hashes = 0;
1099  	mutex_unlock(&info->lock);
1100  
1101  	if (unlikely(cointerra->usbinfo.nodev))
1102  		hashes = -1;
1103  out:
1104  	return hashes;
1105  }
1106  
1107  /* This is used for a work restart. We don't actually perform the work restart
1108   * here but wake up the scanwork loop if it's waiting on the conditional so
1109   * that it can test for the restart message. */
1110  static void cta_wake(struct cgpu_info *cointerra)
1111  {
1112  	struct cointerra_info *info = cointerra->device_data;
1113  
1114  	mutex_lock(&info->lock);
1115  	pthread_cond_signal(&info->wake_cond);
1116  	mutex_unlock(&info->lock);
1117  }
1118  
1119  static void cta_shutdown(struct thr_info *thr)
1120  {
1121  	struct cgpu_info *cointerra = thr->cgpu;
1122  
1123  	cta_close(cointerra);
1124  }
1125  
1126  static void cta_zero_stats(struct cgpu_info *cointerra)
1127  {
1128  	struct cointerra_info *info = cointerra->device_data;
1129  	int i;
1130  
1131  	info->tot_calc_hashes = 0;
1132  	info->tot_reset_hashes = info->tot_hashes;
1133  	info->tot_share_hashes = 0;
1134  	cta_zero_corehashes(info);
1135  
1136  	for (i = 0; i < 16 * 2; i++)
1137  		info->old_hashes[i] = 0;
1138  }
1139  
1140  static int bits_set(char v)
1141  {
1142  	int c;
1143  
1144  	for (c = 0; v; c++)
1145  		v &= v - 1;
1146  	return c;
1147  }
1148  
1149  static struct api_data *cta_api_stats(struct cgpu_info *cgpu)
1150  {
1151  	struct api_data *root = NULL;
1152  	struct cointerra_info *info = cgpu->device_data;
1153  	double dev_runtime = cgpu_runtime(cgpu);
1154  	int i, asic, core, coreno = 0;
1155  	struct timeval now;
1156  	char bitmaphex[36];
1157  	uint64_t ghs, val;
1158  	char buf[64];
1159  	uint32_t runtime = cgpu_runtime(cgpu);
1160  
1161  	/* Info data */
1162  	root = api_add_uint16(root, "HW Revision", &info->hwrev, false);
1163  	root = api_add_uint32(root, "Serial", &info->serial, false);
1164  	root = api_add_uint8(root, "Asics", &info->asics, false);
1165  	root = api_add_uint8(root, "Dies", &info->dies, false);
1166  	root = api_add_uint16(root, "Cores", &info->cores, false);
1167  	root = api_add_uint8(root, "Board number", &info->board_number, false);
1168  	sprintf(buf, "%u.%u.%u", info->fwrev[0], info->fwrev[1], info->fwrev[2]);
1169  	root = api_add_string(root, "FW Revision", buf, true);
1170  	sprintf(buf, "%04u-%02u-%02u", info->fw_year, info->fw_month, info->fw_day);
1171  	root = api_add_string(root, "FW Date", buf, true);
1172  	root = api_add_uint8(root, "Init diffbits", &info->init_diffbits, false);
1173  	root = api_add_uint8(root, "Min diffbits", &info->min_diffbits, false);
1174  	root = api_add_uint8(root, "Max diffbits", &info->max_diffbits, false);
1175  
1176  	/* Status readings */
1177  	for (i = 0; i < CTA_CORES; i++) {
1178  		sprintf(buf, "CoreTemp%d", i);
1179  		root = api_add_int16(root, buf, &info->coretemp[i], false);
1180  	}
1181  	root = api_add_int16(root, "Ambient Low", &info->ambtemp_low, false);
1182  	root = api_add_int16(root, "Ambient Avg", &info->ambtemp_avg, false);
1183  	root = api_add_int16(root, "Ambient High", &info->ambtemp_high, false);
1184  	for (i = 0; i < CTA_PUMPS; i++) {
1185  		sprintf(buf, "PumpRPM%d", i);
1186  		root = api_add_uint16(root, buf, &info->pump_tachs[i], false);
1187  	}
1188  	for (i = 0; i < CTA_FANS; i++) {
1189  		sprintf(buf, "FanRPM%d", i);
1190  		root = api_add_uint16(root, buf, &info->fan_tachs[i], false);
1191  	}
1192  	for (i = 0; i < CTA_CORES; i++) {
1193  		sprintf(buf, "CoreFreqs%d", i);
1194  		root = api_add_uint16(root, buf, &info->corefreqs[i], false);
1195  	}
1196  
1197  	for (i = 0; i < CTA_CORES; i++) {
1198  		sprintf(buf, "CoreVolts%d", i);
1199  		root = api_add_uint16(root, buf, &info->corevolts[i], false);
1200  	}
1201  	root = api_add_uint16(root, "Volts3.3", &info->volts33, false);
1202  	root = api_add_uint16(root, "Volts12", &info->volts12, false);
1203  	root = api_add_uint16(root, "Inactive", &info->inactive, false);
1204  	root = api_add_uint16(root, "Active", &info->active, false);
1205  
1206  	/* Status settings */
1207  	for (i = 0; i < CTA_CORES; i++) {
1208  		sprintf(buf, "CorePerfMode%d", i);
1209  		root = api_add_uint8(root, buf, &info->coreperf[i], false);
1210  	}
1211  	for (i = 0; i < CTA_FANS; i++) {
1212  		sprintf(buf, "FanSpeed%d", i);
1213  		root = api_add_uint8(root, buf, &info->fanspeed[i], false);
1214  	}
1215  	root = api_add_uint8(root, "DiesActive", &info->dies_active, false);
1216  	for (i = 0; i < CTA_CORES; i++) {
1217  		sprintf(buf, "PipesEnabled%d", i);
1218  		root = api_add_uint8(root, buf, &info->pipes_enabled[i], false);
1219  	}
1220  
1221  	/* Status debug */
1222  	root = api_add_int(root, "Underruns", &info->tot_underruns, false);
1223  	for (i = 0; i < CTA_CORES; i++) {
1224  		sprintf(buf, "HWErrors%d", i);
1225  		root = api_add_uint16(root, buf, &info->tot_hw_errors[i], false);
1226  	}
1227  	ghs = info->tot_calc_hashes / dev_runtime;
1228  	root = api_add_uint64(root, "Calc hashrate", &ghs, true);
1229  	ghs = (info->tot_hashes - info->tot_reset_hashes) / dev_runtime;
1230  	root = api_add_uint64(root, "Hashrate", &ghs, true);
1231  	//root = api_add_uint64(root, "cgminer 15m Hashrate", &cgpu->rolling15, true);
1232  	// get runtime in 30 second steps
1233  	runtime = runtime / 30;
1234  	// store the current hashes
1235  	info->old_hashes[runtime%32] = info->tot_calc_hashes;
1236  	// calc the 15 minute average hashrate
1237  	ghs = (info->old_hashes[(runtime+31)%32] - info->old_hashes[(runtime+1)%32])/(15*60);
1238  	root = api_add_uint64(root, "15m Hashrate", &ghs, true);
1239  	ghs = info->tot_share_hashes / dev_runtime;
1240  	root = api_add_uint64(root, "Share hashrate", &ghs, true);
1241  	root = api_add_uint64(root, "Total calc hashes", &info->tot_calc_hashes, false);
1242  	ghs = info->tot_hashes - info->tot_reset_hashes;
1243  	root = api_add_uint64(root, "Total hashes", &ghs, true);
1244  	root = api_add_uint64(root, "Total raw hashes", &info->tot_hashes, false);
1245  	root = api_add_uint64(root, "Total share hashes", &info->tot_share_hashes, false);
1246  	root = api_add_uint64(root, "Total flushed hashes", &info->tot_flushed_hashes, false);
1247  	val = cgpu->diff_accepted * 0x100000000ull;
1248  	root = api_add_uint64(root, "Accepted hashes", &val, true);
1249  	ghs = val / dev_runtime;
1250  	root = api_add_uint64(root, "Accepted hashrate", &ghs, true);
1251  	val = cgpu->diff_rejected * 0x100000000ull;
1252  	root = api_add_uint64(root, "Rejected hashes", &val, true);
1253  	ghs = val / dev_runtime;
1254  	root = api_add_uint64(root, "Rejected hashrate", &ghs, true);
1255  
1256  	cgtime(&now);
1257  	dev_runtime = tdiff(&now, &info->core_hash_start);
1258  	if (dev_runtime < 1)
1259  		dev_runtime = 1;
1260  	for (i = 0; i < CTA_CORES; i++) {
1261  		sprintf(buf, "Core%d hashrate", i);
1262  		ghs = info->tot_core_hashes[i] / dev_runtime;
1263  		root = api_add_uint64(root, buf, &ghs, true);
1264  	}
1265  	root = api_add_uint32(root, "Uptime",&info->uptime,false);
1266  	for (asic = 0; asic < 2; asic++) {
1267  		for (core = 0; core < 4; core++) {
1268  			char bitmapcount[40], asiccore[12];
1269  			int count = 0;
1270  
1271  			sprintf(asiccore, "Asic%dCore%d", asic, core);
1272  			__bin2hex(bitmaphex, &info->pipe_bitmap[coreno], 16);
1273  			for (i = coreno; i < coreno + 16; i++)
1274  				count += bits_set(info->pipe_bitmap[i]);
1275  			snprintf(bitmapcount, 40, "%d:%s", count, bitmaphex);
1276  			root = api_add_string(root, asiccore, bitmapcount, true);
1277  			coreno += 16;
1278  		}
1279  	}
1280  	root = api_add_uint8(root, "AV", &info->autovoltage, false);
1281  	root = api_add_uint8(root, "Power Supply Percent", &info->current_ps_percent, false);
1282  	//if (info->power_used != 0) {
1283  	{
1284  		double value = info->power_used/100.0;
1285  
1286  		value *= (info->power_voltage/100.0);
1287  		root = api_add_double(root, "Power Used", &value, true);
1288  	}
1289  		root = api_add_uint16(root, "IOUT", &info->power_used, false);
1290  		root = api_add_uint16(root, "VOUT", &info->power_voltage, false);
1291  		root = api_add_uint16(root, "IIN", &info->ipower_used, false);
1292  		root = api_add_uint16(root, "VIN", &info->ipower_voltage, false);
1293  		root = api_add_uint16(root, "PSTemp1", &info->power_temps[0], false);
1294  		root = api_add_uint16(root, "PSTemp2", &info->power_temps[1], false);
1295  	//}
1296  
1297  	for (core = 0; core < CTA_CORES; core++) {
1298  		char name[20];
1299  		char str[20];
1300  		double value;
1301  
1302  		sprintf(name,"IRVIN%d",core+1);
1303  		value = info->irstat_vin[core]/100.0;
1304  		root = api_add_double(root,name,&value,true);
1305  		sprintf(name,"IRIIN%d",core+1);
1306  		value = info->irstat_iin[core]/100.0;
1307  		root = api_add_double(root,name,&value,true);
1308  		sprintf(name,"IRVOUT%d",core+1);
1309  		value = info->irstat_vout[core]/100.0;
1310  		root = api_add_double(root,name,&value,true);
1311  		sprintf(name,"IRIOUT%d",core+1);
1312  		value = info->irstat_iout[core]/100.0;
1313  		root = api_add_double(root,name,&value,true);
1314  		sprintf(name,"IRTEMP1_%d",core+1);
1315  		value = info->irstat_temp1[core]/100.0;
1316  		root = api_add_double(root,name,&value,true);
1317  		sprintf(name,"IRTEMP2_%d",core+1);
1318  		value = info->irstat_temp2[core]/100.0;
1319  		root = api_add_double(root,name,&value,true);
1320  		sprintf(name,"IRPOUT%d",core+1);
1321  		value = info->irstat_pout[core]/100.0;
1322  		root = api_add_double(root,name,&value,true);
1323  		sprintf(name,"IRPIN%d",core+1);
1324  		value = info->irstat_pin[core]/100.0;
1325  		root = api_add_double(root,name,&value,true);
1326  		sprintf(name,"IREFFICIENCY%d",core+1);
1327  		value = info->irstat_efficiency[core]/100.0;
1328  		root = api_add_double(root,name,&value,true);
1329  		sprintf(name,"IRSTATUS%d",core+1);
1330  		//root = api_add_uint16(root,name,&info->irstat_status[core],false);
1331  		sprintf(str,"0x%04X",info->irstat_status[core]);
1332  			root = api_add_string(root, name, str, true);
1333  	}
1334  
1335  	for (i = 0; i < CTA_CORES; i++) {
1336  		sprintf(buf, "CoreFmatch%d", i);
1337  		root = api_add_uint16(root, buf, &info->fmatch_errors[i], false);
1338  	}
1339  
1340  	return root;
1341  }
1342  
1343  static void cta_statline_before(char *buf, size_t bufsiz, struct cgpu_info *cointerra)
1344  {
1345  	struct cointerra_info *info = cointerra->device_data;
1346  	double max_volt = 0;
1347  	int freq = 0, i;
1348  
1349  	for (i = 0; i < CTA_CORES; i++) {
1350  		if (info->corevolts[i] > max_volt)
1351  			max_volt = info->corevolts[i];
1352  		if (info->corefreqs[i] > freq)
1353  			freq = info->corefreqs[i];
1354  	}
1355  	max_volt /= 1000;
1356  
1357  	tailsprintf(buf, bufsiz, "%3dMHz %3.1fC %3.2fV", freq, cointerra->temp, max_volt);
1358  }
1359  
1360  struct device_drv cointerra_drv = {
1361  	.drv_id = DRIVER_cointerra,
1362  	.dname = "cointerra",
1363  	.name = "CTA",
1364  	.drv_detect = cta_detect,
1365  	.thread_prepare = cta_prepare,
1366  	.hash_work = hash_queued_work,
1367  	.queue_full = cta_fill,
1368  	.update_work = cta_update_work,
1369  	.scanwork = cta_scanwork,
1370  	.flush_work = cta_wake,
1371  	.get_api_stats = cta_api_stats,
1372  	.get_statline_before = cta_statline_before,
1373  	.thread_shutdown = cta_shutdown,
1374  	.zero_stats = cta_zero_stats,
1375  	.max_diff = 64, // Set it below the actual limit to check nonces
1376  };