/ driver-avalon2.c
driver-avalon2.c
   1  /*
   2   * Copyright 2013-2015 Con Kolivas <kernel@kolivas.org>
   3   * Copyright 2012-2014 Xiangfu <xiangfu@openmobilefree.com>
   4   * Copyright 2012 Luke Dashjr
   5   * Copyright 2012 Andrew Smith
   6   *
   7   * This program is free software; you can redistribute it and/or modify it
   8   * under the terms of the GNU General Public License as published by the Free
   9   * Software Foundation; either version 3 of the License, or (at your option)
  10   * any later version.  See COPYING for more details.
  11   */
  12  
  13  #include "config.h"
  14  
  15  #include <limits.h>
  16  #include <pthread.h>
  17  #include <stdio.h>
  18  #include <sys/time.h>
  19  #include <sys/types.h>
  20  #include <dirent.h>
  21  #include <unistd.h>
  22  #ifndef WIN32
  23    #include <termios.h>
  24    #include <sys/stat.h>
  25    #include <fcntl.h>
  26    #ifndef O_CLOEXEC
  27      #define O_CLOEXEC 0
  28    #endif
  29  #else
  30    #include <io.h>
  31  #endif
  32  
  33  #include "elist.h"
  34  #include "miner.h"
  35  #include "fpgautils.h"
  36  #include "driver-avalon2.h"
  37  #include "crc.h"
  38  #include "sha2.h"
  39  
  40  #define ASSERT1(condition) __maybe_unused static char sizeof_uint32_t_must_be_4[(condition)?1:-1]
  41  ASSERT1(sizeof(uint32_t) == 4);
  42  
  43  #define get_fan_pwm(v)	(AVA2_PWM_MAX - (v) * AVA2_PWM_MAX / 100)
  44  
  45  int opt_avalon2_freq_min;
  46  int opt_avalon2_freq_max;
  47  
  48  int opt_avalon2_fan_min = AVA2_DEFAULT_FAN_MIN;
  49  int opt_avalon2_fan_max = AVA2_DEFAULT_FAN_MAX;
  50  static int avalon2_fan_min = get_fan_pwm(AVA2_DEFAULT_FAN_MIN);
  51  static int avalon2_fan_max = get_fan_pwm(AVA2_DEFAULT_FAN_MAX);
  52  
  53  int opt_avalon2_voltage_min;
  54  int opt_avalon2_voltage_max;
  55  
  56  int opt_avalon2_overheat = AVALON2_TEMP_OVERHEAT;
  57  int opt_avalon2_polling_delay = AVALON2_DEFAULT_POLLING_DELAY;
  58  
  59  enum avalon2_fan_fixed opt_avalon2_fan_fixed = FAN_AUTO;
  60  
  61  #define UNPACK32(x, str)			\
  62  {						\
  63  	*((str) + 3) = (uint8_t) ((x)      );	\
  64  	*((str) + 2) = (uint8_t) ((x) >>  8);	\
  65  	*((str) + 1) = (uint8_t) ((x) >> 16);	\
  66  	*((str) + 0) = (uint8_t) ((x) >> 24);	\
  67  }
  68  
  69  static void sha256_prehash(const unsigned char *message, unsigned int len, unsigned char *digest)
  70  {
  71  	sha256_ctx ctx;
  72  	int i;
  73  	sha256_init(&ctx);
  74  	sha256_update(&ctx, message, len);
  75  
  76  	for (i = 0; i < 8; i++) {
  77  		UNPACK32(ctx.h[i], &digest[i << 2]);
  78  	}
  79  }
  80  
  81  static inline uint8_t rev8(uint8_t d)
  82  {
  83  	int i;
  84  	uint8_t out = 0;
  85  
  86  	/* (from left to right) */
  87  	for (i = 0; i < 8; i++)
  88  		if (d & (1 << i))
  89  		out |= (1 << (7 - i));
  90  
  91  	return out;
  92  }
  93  
  94  char *set_avalon2_fan(char *arg)
  95  {
  96  	int val1, val2, ret;
  97  
  98  	ret = sscanf(arg, "%d-%d", &val1, &val2);
  99  	if (ret < 1)
 100  		return "No values passed to avalon2-fan";
 101  	if (ret == 1)
 102  		val2 = val1;
 103  
 104  	if (val1 < 0 || val1 > 100 || val2 < 0 || val2 > 100 || val2 < val1)
 105  		return "Invalid value passed to avalon2-fan";
 106  
 107  	opt_avalon2_fan_min = val1;
 108  	opt_avalon2_fan_max = val2;
 109  	avalon2_fan_min = get_fan_pwm(val1);
 110  	avalon2_fan_max = get_fan_pwm(val2);
 111  
 112  	return NULL;
 113  }
 114  
 115  char *set_avalon2_fixed_speed(enum avalon2_fan_fixed *f)
 116  {
 117  	*f = FAN_FIXED;
 118  	return NULL;
 119  }
 120  
 121  char *set_avalon2_freq(char *arg)
 122  {
 123  	int val1, val2, ret;
 124  
 125  	ret = sscanf(arg, "%d-%d", &val1, &val2);
 126  	if (ret < 1)
 127  		return "No values passed to avalon2-freq";
 128  	if (ret == 1)
 129  		val2 = val1;
 130  
 131  	if (val1 < AVA2_DEFAULT_FREQUENCY_MIN || val1 > AVA2_DEFAULT_FREQUENCY_MAX ||
 132  	    val2 < AVA2_DEFAULT_FREQUENCY_MIN || val2 > AVA2_DEFAULT_FREQUENCY_MAX ||
 133  	    val2 < val1)
 134  		return "Invalid value passed to avalon2-freq";
 135  
 136  	opt_avalon2_freq_min = val1;
 137  	opt_avalon2_freq_max = val2;
 138  
 139  	return NULL;
 140  }
 141  
 142  char *set_avalon2_voltage(char *arg)
 143  {
 144  	int val1, val2, ret;
 145  
 146  	ret = sscanf(arg, "%d-%d", &val1, &val2);
 147  	if (ret < 1)
 148  		return "No values passed to avalon2-voltage";
 149  	if (ret == 1)
 150  		val2 = val1;
 151  
 152  	if (val1 < AVA2_DEFAULT_VOLTAGE_MIN || val1 > AVA2_DEFAULT_VOLTAGE_MAX ||
 153  	    val2 < AVA2_DEFAULT_VOLTAGE_MIN || val2 > AVA2_DEFAULT_VOLTAGE_MAX ||
 154  	    val2 < val1)
 155  		return "Invalid value passed to avalon2-voltage";
 156  
 157  	opt_avalon2_voltage_min = val1;
 158  	opt_avalon2_voltage_max = val2;
 159  
 160  	return NULL;
 161  }
 162  
 163  static int avalon2_init_pkg(struct avalon2_pkg *pkg, uint8_t type, uint8_t idx, uint8_t cnt)
 164  {
 165  	unsigned short crc;
 166  
 167  	pkg->head[0] = AVA2_H1;
 168  	pkg->head[1] = AVA2_H2;
 169  
 170  	pkg->type = type;
 171  	pkg->idx = idx;
 172  	pkg->cnt = cnt;
 173  
 174  	crc = crc16(pkg->data, AVA2_P_DATA_LEN);
 175  
 176  	pkg->crc[0] = (crc & 0xff00) >> 8;
 177  	pkg->crc[1] = crc & 0x00ff;
 178  	return 0;
 179  }
 180  
 181  static int job_idcmp(uint8_t *job_id, char *pool_job_id)
 182  {
 183  	int job_id_len;
 184  	unsigned short crc, crc_expect;
 185  
 186  	if (!pool_job_id)
 187  		return 1;
 188  
 189  	job_id_len = strlen(pool_job_id);
 190  	crc_expect = crc16((unsigned char *)pool_job_id, job_id_len);
 191  
 192  	crc = job_id[0] << 8 | job_id[1];
 193  
 194  	if (crc_expect == crc)
 195  		return 0;
 196  
 197  	applog(LOG_DEBUG, "Avalon2: job_id not match! [%04x:%04x (%s)]",
 198  	       crc, crc_expect, pool_job_id);
 199  
 200  	return 1;
 201  }
 202  
 203  static inline int get_temp_max(struct avalon2_info *info)
 204  {
 205  	int i;
 206  	for (i = 0; i < 2 * AVA2_DEFAULT_MODULARS; i++) {
 207  		if (info->temp_max <= info->temp[i])
 208  			info->temp_max = info->temp[i];
 209  	}
 210  	return info->temp_max;
 211  }
 212  
 213  static inline int get_current_temp_max(struct avalon2_info *info)
 214  {
 215  	int i;
 216  	int t = info->temp[0];
 217  
 218  	for (i = 1; i < 2 * AVA2_DEFAULT_MODULARS; i++) {
 219  		if (info->temp[i] > t)
 220  			t = info->temp[i];
 221  	}
 222  	return t;
 223  }
 224  
 225  /* http://www.onsemi.com/pub_link/Collateral/ADP3208D.PDF */
 226  static inline uint32_t encode_voltage(uint32_t v)
 227  {
 228  	return rev8((0x78 - v / 125) << 1 | 1) << 8;
 229  }
 230  
 231  static inline uint32_t decode_voltage(uint32_t v)
 232  {
 233  	return (0x78 - (rev8(v >> 8) >> 1)) * 125;
 234  }
 235  
 236  static void adjust_fan(struct avalon2_info *info)
 237  {
 238  	int t;
 239  
 240  	if (opt_avalon2_fan_fixed == FAN_FIXED) {
 241  		info->fan_pct = opt_avalon2_fan_min;
 242  		info->fan_pwm = get_fan_pwm(info->fan_pct);
 243  		return;
 244  	}
 245  
 246  	t = get_current_temp_max(info);
 247  
 248  	/* TODO: Add options for temperature range and fan adjust function */
 249  	if (t < 60)
 250  		info->fan_pct = opt_avalon2_fan_min;
 251  	else if (t > 80)
 252  		info->fan_pct = opt_avalon2_fan_max;
 253  	else
 254  		info->fan_pct = (t - 60) * (opt_avalon2_fan_max - opt_avalon2_fan_min) / 20 + opt_avalon2_fan_min;
 255  
 256  	info->fan_pwm = get_fan_pwm(info->fan_pct);
 257  }
 258  
 259  static inline int mm_cmp_1404(struct avalon2_info *info, int modular)
 260  {
 261  	/* <= 1404 return 1 */
 262  	char *mm_1404 = "1404";
 263  	return strncmp(info->mm_version[modular] + 2, mm_1404, 4) > 0 ? 0 : 1;
 264  }
 265  
 266  static inline int mm_cmp_1406(struct avalon2_info *info)
 267  {
 268  	/* <= 1406 return 1 */
 269  	char *mm_1406 = "1406";
 270  	int i;
 271  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 272  		if (info->enable[i] &&
 273  		    strncmp(info->mm_version[i] + 2, mm_1406, 4) <= 0)
 274  			return 1;
 275  	}
 276  
 277  	return 0;
 278  }
 279  
 280  static int decode_pkg(struct thr_info *thr, struct avalon2_ret *ar, uint8_t *pkg)
 281  {
 282  	struct cgpu_info *avalon2 = thr->cgpu;
 283  	struct avalon2_info *info = avalon2->device_data;
 284  	struct pool *pool, *real_pool, *pool_stratum = &info->pool;
 285  
 286  	unsigned int expected_crc;
 287  	unsigned int actual_crc;
 288  	uint32_t nonce, nonce2, miner, modular_id;
 289  	int pool_no;
 290  	uint8_t job_id[4];
 291  	int tmp;
 292  
 293  	int type = AVA2_GETS_ERROR;
 294  
 295  	memcpy((uint8_t *)ar, pkg, AVA2_READ_SIZE);
 296  
 297  	if (ar->head[0] == AVA2_H1 && ar->head[1] == AVA2_H2) {
 298  		expected_crc = crc16(ar->data, AVA2_P_DATA_LEN);
 299  		actual_crc = (ar->crc[0] & 0xff) |
 300  			((ar->crc[1] & 0xff) << 8);
 301  
 302  		type = ar->type;
 303  		applog(LOG_DEBUG, "Avalon2: %d: expected crc(%04x), actual_crc(%04x)",
 304  		       type, expected_crc, actual_crc);
 305  		if (expected_crc != actual_crc)
 306  			goto out;
 307  
 308  		memcpy(&modular_id, ar->data + 28, 4);
 309  		modular_id = be32toh(modular_id);
 310  		if (modular_id > 3)
 311  			modular_id = 0;
 312  
 313  		switch(type) {
 314  		case AVA2_P_NONCE:
 315  			applog(LOG_DEBUG, "Avalon2: AVA2_P_NONCE");
 316  			memcpy(&miner, ar->data + 0, 4);
 317  			memcpy(&pool_no, ar->data + 4, 4);
 318  			memcpy(&nonce2, ar->data + 8, 4);
 319  			/* Calc time    ar->data + 12 */
 320  			memcpy(&nonce, ar->data + 16, 4);
 321  			memcpy(job_id, ar->data + 20, 4);
 322  
 323  			miner = be32toh(miner);
 324  			pool_no = be32toh(pool_no);
 325  			if (miner >= AVA2_DEFAULT_MINERS ||
 326  			    modular_id >= AVA2_DEFAULT_MINERS ||
 327  			    pool_no >= total_pools ||
 328  			    pool_no < 0) {
 329  				applog(LOG_DEBUG, "Avalon2: Wrong miner/pool/id no %d,%d,%d", miner, pool_no, modular_id);
 330  				break;
 331  			} else
 332  				info->matching_work[modular_id * AVA2_DEFAULT_MINERS + miner]++;
 333  			nonce2 = be32toh(nonce2);
 334  			nonce = be32toh(nonce);
 335  			nonce -= 0x180;
 336  
 337  			applog(LOG_DEBUG, "Avalon2: Found! %d: (%08x) (%08x)",
 338  			       pool_no, nonce2, nonce);
 339  
 340  			real_pool = pool = pools[pool_no];
 341  			if (job_idcmp(job_id, pool->swork.job_id)) {
 342  				if (!job_idcmp(job_id, pool_stratum->swork.job_id)) {
 343  					applog(LOG_DEBUG, "Avalon2: Match to previous stratum! (%s)", pool_stratum->swork.job_id);
 344  					pool = pool_stratum;
 345  				} else {
 346  					applog(LOG_ERR, "Avalon2: Cannot match to any stratum! (%s)", pool->swork.job_id);
 347  					break;
 348  				}
 349  			}
 350  
 351  			if (submit_nonce2_nonce(thr, pool, real_pool, nonce2, nonce, 0))
 352  				info->failing = false;
 353  			break;
 354  		case AVA2_P_STATUS:
 355  			applog(LOG_DEBUG, "Avalon2: AVA2_P_STATUS");
 356  			memcpy(&tmp, ar->data, 4);
 357  			tmp = be32toh(tmp);
 358  			info->temp[0 + modular_id * 2] = tmp >> 16;
 359  			info->temp[1 + modular_id * 2] = tmp & 0xffff;
 360  
 361  			memcpy(&tmp, ar->data + 4, 4);
 362  			tmp = be32toh(tmp);
 363  			info->fan[0 + modular_id * 2] = tmp >> 16;
 364  			info->fan[1 + modular_id * 2] = tmp & 0xffff;
 365  
 366  			memcpy(&(info->get_frequency[modular_id]), ar->data + 8, 4);
 367  			memcpy(&(info->get_voltage[modular_id]), ar->data + 12, 4);
 368  			memcpy(&(info->local_work[modular_id]), ar->data + 16, 4);
 369  			memcpy(&(info->hw_work[modular_id]), ar->data + 20, 4);
 370  			memcpy(&(info->power_good[modular_id]), ar->data + 24, 4);
 371  
 372  			info->get_frequency[modular_id] = be32toh(info->get_frequency[modular_id]);
 373  			if (info->dev_type[modular_id] == AVA2_ID_AVA3)
 374  				info->get_frequency[modular_id] = info->get_frequency[modular_id] * 768 / 65;
 375  			info->get_voltage[modular_id] = be32toh(info->get_voltage[modular_id]);
 376  			info->local_work[modular_id] = be32toh(info->local_work[modular_id]);
 377  			info->hw_work[modular_id] = be32toh(info->hw_work[modular_id]);
 378  
 379  			info->local_works[modular_id] += info->local_work[modular_id];
 380  			info->hw_works[modular_id] += info->hw_work[modular_id];
 381  
 382  			info->get_voltage[modular_id] = decode_voltage(info->get_voltage[modular_id]);
 383  			info->power_good[modular_id] = info->power_good[modular_id]  >> 24;
 384  
 385  			avalon2->temp = get_temp_max(info);
 386  			break;
 387  		case AVA2_P_ACKDETECT:
 388  			applog(LOG_DEBUG, "Avalon2: AVA2_P_ACKDETECT");
 389  			break;
 390  		case AVA2_P_ACK:
 391  			applog(LOG_DEBUG, "Avalon2: AVA2_P_ACK");
 392  			break;
 393  		case AVA2_P_NAK:
 394  			applog(LOG_DEBUG, "Avalon2: AVA2_P_NAK");
 395  			break;
 396  		default:
 397  			applog(LOG_DEBUG, "Avalon2: Unknown response");
 398  			type = AVA2_GETS_ERROR;
 399  			break;
 400  		}
 401  	}
 402  
 403  out:
 404  	return type;
 405  }
 406  
 407  static inline int avalon2_gets(struct cgpu_info *avalon2, uint8_t *buf)
 408  {
 409  	int read_amount = AVA2_READ_SIZE, ret = 0;
 410  	uint8_t *buf_back = buf;
 411  
 412  	while (true) {
 413  		int err;
 414  
 415  		do {
 416  			memset(buf, 0, read_amount);
 417  			err = usb_read(avalon2, (char *)buf, read_amount, &ret, C_AVA2_READ);
 418  			if (unlikely(err && err != LIBUSB_ERROR_TIMEOUT)) {
 419  				applog(LOG_ERR, "Avalon2: Error %d on read in avalon_gets got %d", err, ret);
 420  				return AVA2_GETS_ERROR;
 421  			}
 422  			if (likely(ret >= read_amount)) {
 423  				if (unlikely(buf_back[0] != AVA2_H1 || buf_back[1] != AVA2_H2))
 424  					return AVA2_GETS_ERROR;
 425  				return AVA2_GETS_OK;
 426  			}
 427  			buf += ret;
 428  			read_amount -= ret;
 429  		} while (ret > 0);
 430  
 431  		return AVA2_GETS_TIMEOUT;
 432  	}
 433  }
 434  
 435  static int avalon2_send_pkg(struct cgpu_info *avalon2, const struct avalon2_pkg *pkg)
 436  {
 437  	int err, amount;
 438  	uint8_t buf[AVA2_WRITE_SIZE];
 439  	int nr_len = AVA2_WRITE_SIZE;
 440  
 441  	if (unlikely(avalon2->usbinfo.nodev))
 442  		return AVA2_SEND_ERROR;
 443  
 444  	memcpy(buf, pkg, AVA2_WRITE_SIZE);
 445  	err = usb_write(avalon2, (char *)buf, nr_len, &amount, C_AVA2_WRITE);
 446  	if (err || amount != nr_len) {
 447  		applog(LOG_DEBUG, "Avalon2: Send(%d)!", amount);
 448  		usb_nodev(avalon2);
 449  		return AVA2_SEND_ERROR;
 450  	}
 451  
 452  	return AVA2_SEND_OK;
 453  }
 454  
 455  static void avalon2_stratum_pkgs(struct cgpu_info *avalon2, struct pool *pool)
 456  {
 457  	const int merkle_offset = 36;
 458  	struct avalon2_pkg pkg;
 459  	int i, a, b, tmp;
 460  	unsigned char target[32];
 461  	int job_id_len, n2size;
 462  	unsigned short crc;
 463  	int diff;
 464  
 465  	/* Cap maximum diff in order to still get shares */
 466  	diff = pool->swork.diff;
 467  	if (diff > 64)
 468  		diff = 64;
 469  	else if (unlikely(diff < 1))
 470  		diff = 1;
 471  
 472  	/* Send out the first stratum message STATIC */
 473  	applog(LOG_DEBUG, "Avalon2: Pool stratum message STATIC: %d, %d, %d, %d, %d",
 474  	       pool->coinbase_len,
 475  	       pool->nonce2_offset,
 476  	       pool->n2size,
 477  	       merkle_offset,
 478  	       pool->merkles);
 479  	memset(pkg.data, 0, AVA2_P_DATA_LEN);
 480  	tmp = be32toh(pool->coinbase_len);
 481  	memcpy(pkg.data, &tmp, 4);
 482  
 483  	tmp = be32toh(pool->nonce2_offset);
 484  	memcpy(pkg.data + 4, &tmp, 4);
 485  
 486  	n2size = pool->n2size >= 4 ? 4 : pool->n2size;
 487  	tmp = be32toh(n2size);
 488  	memcpy(pkg.data + 8, &tmp, 4);
 489  
 490  	tmp = be32toh(merkle_offset);
 491  	memcpy(pkg.data + 12, &tmp, 4);
 492  
 493  	tmp = be32toh(pool->merkles);
 494  	memcpy(pkg.data + 16, &tmp, 4);
 495  
 496  	tmp = be32toh(diff);
 497  	memcpy(pkg.data + 20, &tmp, 4);
 498  
 499  	tmp = be32toh((int)pool->pool_no);
 500  	memcpy(pkg.data + 24, &tmp, 4);
 501  
 502  	avalon2_init_pkg(&pkg, AVA2_P_STATIC, 1, 1);
 503  	if (avalon2_send_pkg(avalon2, &pkg))
 504  		return;
 505  
 506  	set_target(target, pool->sdiff);
 507  	memcpy(pkg.data, target, 32);
 508  	if (opt_debug) {
 509  		char *target_str;
 510  		target_str = bin2hex(target, 32);
 511  		applog(LOG_DEBUG, "Avalon2: Pool stratum target: %s", target_str);
 512  		free(target_str);
 513  	}
 514  	avalon2_init_pkg(&pkg, AVA2_P_TARGET, 1, 1);
 515  	if (avalon2_send_pkg(avalon2, &pkg))
 516  		return;
 517  
 518  	applog(LOG_DEBUG, "Avalon2: Pool stratum message JOBS_ID: %s",
 519  	       pool->swork.job_id);
 520  	memset(pkg.data, 0, AVA2_P_DATA_LEN);
 521  
 522  	job_id_len = strlen(pool->swork.job_id);
 523  	crc = crc16((unsigned char *)pool->swork.job_id, job_id_len);
 524  	pkg.data[0] = (crc & 0xff00) >> 8;
 525  	pkg.data[1] = crc & 0x00ff;
 526  	avalon2_init_pkg(&pkg, AVA2_P_JOB_ID, 1, 1);
 527  	if (avalon2_send_pkg(avalon2, &pkg))
 528  		return;
 529  
 530  	if (pool->coinbase_len > AVA2_P_COINBASE_SIZE) {
 531  		int coinbase_len_posthash, coinbase_len_prehash;
 532  		uint8_t coinbase_prehash[32];
 533  		coinbase_len_prehash = pool->nonce2_offset - (pool->nonce2_offset % SHA256_BLOCK_SIZE);
 534  		coinbase_len_posthash = pool->coinbase_len - coinbase_len_prehash;
 535  		sha256_prehash(pool->coinbase, coinbase_len_prehash, coinbase_prehash);
 536  
 537  		a = (coinbase_len_posthash / AVA2_P_DATA_LEN) + 1;
 538  		b = coinbase_len_posthash % AVA2_P_DATA_LEN;
 539  	        memcpy(pkg.data, coinbase_prehash, 32);
 540  	        avalon2_init_pkg(&pkg, AVA2_P_COINBASE, 1, a + (b ? 1 : 0));
 541  	        if (avalon2_send_pkg(avalon2, &pkg))
 542  			return;
 543  	        applog(LOG_DEBUG, "Avalon2: Pool stratum message modified COINBASE: %d %d", a, b);
 544  	        for (i = 1; i < a; i++) {
 545  	                memcpy(pkg.data, pool->coinbase + coinbase_len_prehash + i * 32 - 32, 32);
 546  	                avalon2_init_pkg(&pkg, AVA2_P_COINBASE, i + 1, a + (b ? 1 : 0));
 547  			if (avalon2_send_pkg(avalon2, &pkg))
 548  	                        return;
 549  	        }
 550  	        if (b) {
 551  	                memset(pkg.data, 0, AVA2_P_DATA_LEN);
 552  			memcpy(pkg.data, pool->coinbase + coinbase_len_prehash + i * 32 - 32, b);
 553  	                avalon2_init_pkg(&pkg, AVA2_P_COINBASE, i + 1, i + 1);
 554  	                if (avalon2_send_pkg(avalon2, &pkg))
 555  	                        return;
 556  	        }
 557  	} else {
 558  		a = pool->coinbase_len / AVA2_P_DATA_LEN;
 559  		b = pool->coinbase_len % AVA2_P_DATA_LEN;
 560  		applog(LOG_DEBUG, "Avalon2: Pool stratum message COINBASE: %d %d", a, b);
 561  		for (i = 0; i < a; i++) {
 562  			memcpy(pkg.data, pool->coinbase + i * 32, 32);
 563  			avalon2_init_pkg(&pkg, AVA2_P_COINBASE, i + 1, a + (b ? 1 : 0));
 564  			if (avalon2_send_pkg(avalon2, &pkg))
 565  				return;
 566  		}
 567  		if (b) {
 568  			memset(pkg.data, 0, AVA2_P_DATA_LEN);
 569  			memcpy(pkg.data, pool->coinbase + i * 32, b);
 570  			avalon2_init_pkg(&pkg, AVA2_P_COINBASE, i + 1, i + 1);
 571  			if (avalon2_send_pkg(avalon2, &pkg))
 572  				return;
 573  		}
 574  	}
 575  
 576  
 577  	b = pool->merkles;
 578  	applog(LOG_DEBUG, "Avalon2: Pool stratum message MERKLES: %d", b);
 579  	for (i = 0; i < b; i++) {
 580  		memset(pkg.data, 0, AVA2_P_DATA_LEN);
 581  		memcpy(pkg.data, pool->swork.merkle_bin[i], 32);
 582  		avalon2_init_pkg(&pkg, AVA2_P_MERKLES, i + 1, b);
 583  		if (avalon2_send_pkg(avalon2, &pkg))
 584  			return;
 585  	}
 586  
 587  	applog(LOG_DEBUG, "Avalon2: Pool stratum message HEADER: 4");
 588  	for (i = 0; i < 4; i++) {
 589  		memset(pkg.data, 0, AVA2_P_HEADER);
 590  		memcpy(pkg.data, pool->header_bin + i * 32, 32);
 591  		avalon2_init_pkg(&pkg, AVA2_P_HEADER, i + 1, 4);
 592  		if (avalon2_send_pkg(avalon2, &pkg))
 593  			return;
 594  	}
 595  }
 596  
 597  static void avalon2_initialise(struct cgpu_info *avalon2)
 598  {
 599  	uint32_t ava2_data[2] = { PL2303_VALUE_LINE0, PL2303_VALUE_LINE1 };
 600  	int interface;
 601  
 602  	if (avalon2->usbinfo.nodev)
 603  		return;
 604  
 605  	interface = usb_interface(avalon2);
 606  	// Set Data Control
 607  	usb_transfer(avalon2, PL2303_VENDOR_OUT, PL2303_REQUEST_VENDOR, 8,
 608  		     interface, C_VENDOR);
 609  	if (avalon2->usbinfo.nodev)
 610  		return;
 611  
 612  	usb_transfer(avalon2, PL2303_VENDOR_OUT, PL2303_REQUEST_VENDOR, 9,
 613  		     interface, C_VENDOR);
 614  
 615  	if (avalon2->usbinfo.nodev)
 616  		return;
 617  
 618  	// Set Line Control
 619  	usb_transfer_data(avalon2, PL2303_CTRL_OUT, PL2303_REQUEST_LINE, PL2303_VALUE_LINE,
 620  			  interface, ava2_data, PL2303_VALUE_LINE_SIZE, C_SETLINE);
 621  	if (avalon2->usbinfo.nodev)
 622  		return;
 623  
 624  	// Vendor
 625  	usb_transfer(avalon2, PL2303_VENDOR_OUT, PL2303_REQUEST_VENDOR, PL2303_VALUE_VENDOR,
 626  		     interface, C_VENDOR);
 627  
 628  	if (avalon2->usbinfo.nodev)
 629  		return;
 630  
 631  	// Set More Line Control ?
 632  	usb_transfer(avalon2, PL2303_CTRL_OUT, PL2303_REQUEST_CTRL, 3, interface, C_SETLINE);
 633  }
 634  
 635  static struct cgpu_info *avalon2_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
 636  {
 637  	struct avalon2_info *info;
 638  	int ackdetect;
 639  	int err, amount;
 640  	int tmp, i, j, modular[AVA2_DEFAULT_MODULARS] = {};
 641  	char mm_version[AVA2_DEFAULT_MODULARS][16];
 642  
 643  	struct cgpu_info *avalon2 = usb_alloc_cgpu(&avalon2_drv, 1);
 644  	struct avalon2_pkg detect_pkg;
 645  	struct avalon2_ret ret_pkg;
 646  
 647  	if (!usb_init(avalon2, dev, found)) {
 648  		applog(LOG_ERR, "Avalon2 failed usb_init");
 649  		avalon2 = usb_free_cgpu(avalon2);
 650  		return NULL;
 651  	}
 652  	avalon2_initialise(avalon2);
 653  
 654  	for (j = 0; j < 2; j++) {
 655  		for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 656  			strcpy(mm_version[i], AVA2_MM_VERNULL);
 657  			/* Send out detect pkg */
 658  			memset(detect_pkg.data, 0, AVA2_P_DATA_LEN);
 659  			tmp = be32toh(i);
 660  			memcpy(detect_pkg.data + 28, &tmp, 4);
 661  
 662  			avalon2_init_pkg(&detect_pkg, AVA2_P_DETECT, 1, 1);
 663  			avalon2_send_pkg(avalon2, &detect_pkg);
 664  			err = usb_read(avalon2, (char *)&ret_pkg, AVA2_READ_SIZE, &amount, C_AVA2_READ);
 665  			if (err < 0 || amount != AVA2_READ_SIZE) {
 666  				applog(LOG_DEBUG, "%s %d: Avalon2 failed usb_read with err %d amount %d",
 667  				       avalon2->drv->name, avalon2->device_id, err, amount);
 668  				continue;
 669  			}
 670  			ackdetect = ret_pkg.type;
 671  			applog(LOG_DEBUG, "Avalon2 Detect ID[%d]: %d", i, ackdetect);
 672  			if (ackdetect != AVA2_P_ACKDETECT && modular[i] == 0)
 673  				continue;
 674  			modular[i] = 1;
 675  			memcpy(mm_version[i], ret_pkg.data, 15);
 676  			mm_version[i][15] = '\0';
 677  		}
 678  	}
 679  	if (!modular[0] && !modular[1] && !modular[2] && !modular[3]) {
 680  		applog(LOG_DEBUG, "Not an Avalon2 device");
 681  		usb_uninit(avalon2);
 682  		usb_free_cgpu(avalon2);
 683  		return NULL;
 684  	}
 685  
 686  	/* We have a real Avalon! */
 687  	avalon2->threads = AVA2_MINER_THREADS;
 688  	add_cgpu(avalon2);
 689  
 690  	update_usb_stats(avalon2);
 691  
 692  	applog(LOG_INFO, "%s %d: Found at %s", avalon2->drv->name, avalon2->device_id,
 693  	       avalon2->device_path);
 694  
 695  	avalon2->device_data = cgcalloc(sizeof(struct avalon2_info), 1);
 696  
 697  	info = avalon2->device_data;
 698  
 699  	info->fan_pwm = get_fan_pwm(AVA2_DEFAULT_FAN_PWM);
 700  	info->temp_max = 0;
 701  
 702  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 703  		strcpy(info->mm_version[i], mm_version[i]);
 704  		info->modulars[i] = modular[i];	/* Enable modular */
 705  		info->enable[i] = modular[i];
 706  		info->dev_type[i] = AVA2_ID_AVAX;
 707  
 708  		if (!strncmp((char *)&(info->mm_version[i]), AVA2_FW2_PREFIXSTR, 2)) {
 709  			info->dev_type[i] = AVA2_ID_AVA2;
 710  			info->set_voltage = AVA2_DEFAULT_VOLTAGE_MIN;
 711  			info->set_frequency = AVA2_DEFAULT_FREQUENCY;
 712  		}
 713  		if (!strncmp((char *)&(info->mm_version[i]), AVA2_FW3_PREFIXSTR, 2)) {
 714  			info->dev_type[i] = AVA2_ID_AVA3;
 715  			info->set_voltage = AVA2_AVA3_VOLTAGE;
 716  			info->set_frequency = AVA2_AVA3_FREQUENCY;
 717  		}
 718  	}
 719  
 720  	if (!opt_avalon2_voltage_min)
 721  		opt_avalon2_voltage_min = opt_avalon2_voltage_max = info->set_voltage;
 722  	if (!opt_avalon2_freq_min)
 723  		opt_avalon2_freq_min = opt_avalon2_freq_max = info->set_frequency;
 724  
 725  	return avalon2;
 726  }
 727  
 728  static inline void avalon2_detect(bool __maybe_unused hotplug)
 729  {
 730  	usb_detect(&avalon2_drv, avalon2_detect_one);
 731  }
 732  
 733  static bool avalon2_prepare(struct thr_info *thr)
 734  {
 735  	struct cgpu_info *avalon2 = thr->cgpu;
 736  	struct avalon2_info *info = avalon2->device_data;
 737  
 738  	cglock_init(&info->pool.data_lock);
 739  
 740  	return true;
 741  }
 742  
 743  static int polling(struct thr_info *thr, struct cgpu_info *avalon2, struct avalon2_info *info)
 744  {
 745  	struct avalon2_pkg send_pkg;
 746  	struct avalon2_ret ar;
 747  	int i, tmp;
 748  
 749  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 750  		if (info->modulars[i] && info->enable[i]) {
 751  			uint8_t result[AVA2_READ_SIZE];
 752  			int ret;
 753  
 754  			cgsleep_ms(opt_avalon2_polling_delay);
 755  			memset(send_pkg.data, 0, AVA2_P_DATA_LEN);
 756  
 757  			tmp = be32toh(info->led_red[i]); /* RED LED */
 758  			memcpy(send_pkg.data + 12, &tmp, 4);
 759  
 760  			tmp = be32toh(i); /* ID */
 761  			memcpy(send_pkg.data + 28, &tmp, 4);
 762  			if (info->led_red[i] && mm_cmp_1404(info, i)) {
 763  				avalon2_init_pkg(&send_pkg, AVA2_P_TEST, 1, 1);
 764  				avalon2_send_pkg(avalon2, &send_pkg);
 765  				info->enable[i] = 0;
 766  				continue;
 767  			} else
 768  				avalon2_init_pkg(&send_pkg, AVA2_P_POLLING, 1, 1);
 769  
 770  			avalon2_send_pkg(avalon2, &send_pkg);
 771  			ret = avalon2_gets(avalon2, result);
 772  			if (ret == AVA2_GETS_OK)
 773  				decode_pkg(thr, &ar, result);
 774  		}
 775  	}
 776  
 777  	return 0;
 778  }
 779  
 780  static void copy_pool_stratum(struct avalon2_info *info, struct pool *pool)
 781  {
 782  	int i;
 783  	int merkles = pool->merkles;
 784  	size_t coinbase_len = pool->coinbase_len;
 785  	struct pool *pool_stratum = &info->pool;
 786  
 787  	if (!job_idcmp((unsigned char *)pool->swork.job_id, pool_stratum->swork.job_id))
 788  		return;
 789  
 790  	cg_wlock(&pool_stratum->data_lock);
 791  	free(pool_stratum->swork.job_id);
 792  	free(pool_stratum->nonce1);
 793  	free(pool_stratum->coinbase);
 794  
 795  	pool_stratum->coinbase = cgcalloc(coinbase_len, 1);
 796  	memcpy(pool_stratum->coinbase, pool->coinbase, coinbase_len);
 797  
 798  	for (i = 0; i < pool_stratum->merkles; i++)
 799  		free(pool_stratum->swork.merkle_bin[i]);
 800  	if (merkles) {
 801  		pool_stratum->swork.merkle_bin = cgrealloc(pool_stratum->swork.merkle_bin,
 802  							   sizeof(char *) * merkles + 1);
 803  		for (i = 0; i < merkles; i++) {
 804  			pool_stratum->swork.merkle_bin[i] = cgmalloc(32);
 805  			memcpy(pool_stratum->swork.merkle_bin[i], pool->swork.merkle_bin[i], 32);
 806  		}
 807  	}
 808  
 809  	pool_stratum->sdiff = pool->sdiff;
 810  	pool_stratum->coinbase_len = pool->coinbase_len;
 811  	pool_stratum->nonce2_offset = pool->nonce2_offset;
 812  	pool_stratum->n2size = pool->n2size;
 813  	pool_stratum->merkles = pool->merkles;
 814  
 815  	pool_stratum->swork.job_id = strdup(pool->swork.job_id);
 816  	pool_stratum->nonce1 = strdup(pool->nonce1);
 817  
 818  	memcpy(pool_stratum->ntime, pool->ntime, sizeof(pool_stratum->ntime));
 819  	memcpy(pool_stratum->header_bin, pool->header_bin, sizeof(pool_stratum->header_bin));
 820  	cg_wunlock(&pool_stratum->data_lock);
 821  }
 822  
 823  static void avalon2_update(struct cgpu_info *avalon2)
 824  {
 825  	struct avalon2_info *info = avalon2->device_data;
 826  	struct thr_info *thr = avalon2->thr[0];
 827  	struct avalon2_pkg send_pkg;
 828  	uint32_t tmp, range, start;
 829  	struct work *work;
 830  	struct pool *pool;
 831  
 832  	applog(LOG_DEBUG, "Avalon2: New stratum: restart: %d, update: %d",
 833  	       thr->work_restart, thr->work_update);
 834  	thr->work_update = false;
 835  	thr->work_restart = false;
 836  
 837  	work = get_work(thr, thr->id); /* Make sure pool is ready */
 838  	discard_work(work); /* Don't leak memory */
 839  
 840  	pool = current_pool();
 841  	if (!pool->has_stratum)
 842  		quit(1, "Avalon2: MM have to use stratum pool");
 843  
 844  	if (pool->coinbase_len > AVA2_P_COINBASE_SIZE) {
 845  		applog(LOG_INFO, "Avalon2: MM pool coinbase length(%d) is more than %d",
 846  		       pool->coinbase_len, AVA2_P_COINBASE_SIZE);
 847  		if (mm_cmp_1406(info)) {
 848  			applog(LOG_ERR, "Avalon2: MM version less then 1406");
 849  			return;
 850  		}
 851  		if ((pool->coinbase_len - pool->nonce2_offset + 64) > AVA2_P_COINBASE_SIZE) {
 852  			applog(LOG_ERR, "Avalon2: MM pool modified coinbase length(%d) is more than %d",
 853  			       pool->coinbase_len - pool->nonce2_offset + 64, AVA2_P_COINBASE_SIZE);
 854  			return;
 855  		}
 856  	}
 857  	if (pool->merkles > AVA2_P_MERKLES_COUNT) {
 858  		applog(LOG_ERR, "Avalon2: MM merkles have to less then %d", AVA2_P_MERKLES_COUNT);
 859  		return;
 860  	}
 861  	if (pool->n2size < 3) {
 862  		applog(LOG_ERR, "Avalon2: MM nonce2 size have to >= 3 (%d)", pool->n2size);
 863  		return;
 864  	}
 865  
 866  	cgtime(&info->last_stratum);
 867  	cg_rlock(&pool->data_lock);
 868  	info->pool_no = pool->pool_no;
 869  	copy_pool_stratum(info, pool);
 870  	avalon2_stratum_pkgs(avalon2, pool);
 871  	cg_runlock(&pool->data_lock);
 872  
 873  	/* Configuer the parameter from outside */
 874  	adjust_fan(info);
 875  	info->set_voltage = opt_avalon2_voltage_min;
 876  	info->set_frequency = opt_avalon2_freq_min;
 877  
 878  	/* Set the Fan, Voltage and Frequency */
 879  	memset(send_pkg.data, 0, AVA2_P_DATA_LEN);
 880  
 881  	tmp = be32toh(info->fan_pwm);
 882  	memcpy(send_pkg.data, &tmp, 4);
 883  
 884  	applog(LOG_INFO, "Avalon2: Temp max: %d, Cut off temp: %d",
 885  	       get_current_temp_max(info), opt_avalon2_overheat);
 886  	if (get_current_temp_max(info) >= opt_avalon2_overheat)
 887  		tmp = encode_voltage(0);
 888  	else
 889  		tmp = encode_voltage(info->set_voltage);
 890  	tmp = be32toh(tmp);
 891  	memcpy(send_pkg.data + 4, &tmp, 4);
 892  
 893  	tmp = be32toh(info->set_frequency);
 894  	memcpy(send_pkg.data + 8, &tmp, 4);
 895  
 896  	/* Configure the nonce2 offset and range */
 897  	if (pool->n2size == 3)
 898  		range = 0xffffff / (total_devices + 1);
 899  	else
 900  		range = 0xffffffff / (total_devices + 1);
 901  	start = range * (avalon2->device_id + 1);
 902  
 903  	tmp = be32toh(start);
 904  	memcpy(send_pkg.data + 12, &tmp, 4);
 905  
 906  	tmp = be32toh(range);
 907  	memcpy(send_pkg.data + 16, &tmp, 4);
 908  
 909  	/* Package the data */
 910  	avalon2_init_pkg(&send_pkg, AVA2_P_SET, 1, 1);
 911  	avalon2_send_pkg(avalon2, &send_pkg);
 912  }
 913  
 914  static int64_t avalon2_scanhash(struct thr_info *thr)
 915  {
 916  	struct timeval current_stratum;
 917  	struct cgpu_info *avalon2 = thr->cgpu;
 918  	struct avalon2_info *info = avalon2->device_data;
 919  	int stdiff;
 920  	int64_t h;
 921  	int i;
 922  
 923  	if (unlikely(avalon2->usbinfo.nodev)) {
 924  		applog(LOG_ERR, "%s %d: Device disappeared, shutting down thread",
 925  		       avalon2->drv->name, avalon2->device_id);
 926  		return -1;
 927  	}
 928  
 929  	/* Stop polling the device if there is no stratum in 3 minutes, network is down */
 930  	cgtime(&current_stratum);
 931  	if (tdiff(&current_stratum, &(info->last_stratum)) > (double)(3.0 * 60.0))
 932  		return 0;
 933  
 934  	polling(thr, avalon2, info);
 935  
 936  	stdiff = share_work_tdiff(avalon2);
 937  	if (unlikely(info->failing)) {
 938  		if (stdiff > 120) {
 939  			applog(LOG_ERR, "%s %d: No valid shares for over 2 minutes, shutting down thread",
 940  			       avalon2->drv->name, avalon2->device_id);
 941  			return -1;
 942  		}
 943  	} else if (stdiff > 60) {
 944  		applog(LOG_ERR, "%s %d: No valid shares for over 1 minute, issuing a USB reset",
 945  		       avalon2->drv->name, avalon2->device_id);
 946  		usb_reset(avalon2);
 947  		info->failing = true;
 948  
 949  	}
 950  
 951  	h = 0;
 952  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 953  		h += info->enable[i] ? (info->local_work[i] - info->hw_work[i]) : 0;
 954  	}
 955  	return h * 0xffffffff;
 956  }
 957  
 958  static struct api_data *avalon2_api_stats(struct cgpu_info *cgpu)
 959  {
 960  	struct api_data *root = NULL;
 961  	struct avalon2_info *info = cgpu->device_data;
 962  	int i, j, a, b;
 963  	char buf[24];
 964  	double hwp;
 965  	int minerindex, minercount;
 966  
 967  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 968  		if(info->dev_type[i] == AVA2_ID_AVAX)
 969  			continue;
 970  		sprintf(buf, "ID%d MM Version", i + 1);
 971  		root = api_add_string(root, buf, (char *)&(info->mm_version[i]), false);
 972  	}
 973  
 974  	minerindex = 0;
 975  	minercount = 0;
 976  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 977  		if (info->dev_type[i] == AVA2_ID_AVAX) {
 978  			minerindex += AVA2_DEFAULT_MINERS;
 979  			continue;
 980  		}
 981  
 982  		if (info->dev_type[i] == AVA2_ID_AVA2)
 983  			minercount = AVA2_DEFAULT_MINERS;
 984  
 985  		if (info->dev_type[i] == AVA2_ID_AVA3)
 986  			minercount = AVA2_AVA3_MINERS;
 987  
 988  		for (j = minerindex; j < (minerindex + minercount); j++) {
 989  			sprintf(buf, "Match work count%02d", j+1);
 990  			root = api_add_int(root, buf, &(info->matching_work[j]), false);
 991  		}
 992  		minerindex += AVA2_DEFAULT_MINERS;
 993  	}
 994  
 995  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
 996  		if(info->dev_type[i] == AVA2_ID_AVAX)
 997  			continue;
 998  		sprintf(buf, "Local works%d", i + 1);
 999  		root = api_add_int(root, buf, &(info->local_works[i]), false);
1000  	}
1001  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
1002  		if(info->dev_type[i] == AVA2_ID_AVAX)
1003  			continue;
1004  		sprintf(buf, "Hardware error works%d", i + 1);
1005  		root = api_add_int(root, buf, &(info->hw_works[i]), false);
1006  	}
1007  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
1008  		if(info->dev_type[i] == AVA2_ID_AVAX)
1009  			continue;
1010  		a = info->hw_works[i];
1011  		b = info->local_works[i];
1012  		hwp = b ? ((double)a / (double)b) : 0;
1013  
1014  		sprintf(buf, "Device hardware error%d%%", i + 1);
1015  		root = api_add_percent(root, buf, &hwp, true);
1016  	}
1017  	for (i = 0; i < 2 * AVA2_DEFAULT_MODULARS; i++) {
1018  		if(info->dev_type[i/2] == AVA2_ID_AVAX)
1019  			continue;
1020  		sprintf(buf, "Temperature%d", i + 1);
1021  		root = api_add_int(root, buf, &(info->temp[i]), false);
1022  	}
1023  	for (i = 0; i < 2 * AVA2_DEFAULT_MODULARS; i++) {
1024  		if(info->dev_type[i/2] == AVA2_ID_AVAX)
1025  			continue;
1026  		sprintf(buf, "Fan%d", i + 1);
1027  		root = api_add_int(root, buf, &(info->fan[i]), false);
1028  	}
1029  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
1030  		if(info->dev_type[i] == AVA2_ID_AVAX)
1031  			continue;
1032  		sprintf(buf, "Voltage%d", i + 1);
1033  		root = api_add_int(root, buf, &(info->get_voltage[i]), false);
1034  	}
1035  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
1036  		if(info->dev_type[i] == AVA2_ID_AVAX)
1037  			continue;
1038  		sprintf(buf, "Frequency%d", i + 1);
1039  		root = api_add_int(root, buf, &(info->get_frequency[i]), false);
1040  	}
1041  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
1042  		if(info->dev_type[i] == AVA2_ID_AVAX)
1043  			continue;
1044  		sprintf(buf, "Power good %02x", i + 1);
1045  		root = api_add_int(root, buf, &(info->power_good[i]), false);
1046  	}
1047  	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
1048  		if(info->dev_type[i] == AVA2_ID_AVAX)
1049  			continue;
1050  		sprintf(buf, "Led %02x", i + 1);
1051  		root = api_add_int(root, buf, &(info->led_red[i]), false);
1052  	}
1053  
1054  	return root;
1055  }
1056  
1057  static void avalon2_statline_before(char *buf, size_t bufsiz, struct cgpu_info *avalon2)
1058  {
1059  	struct avalon2_info *info = avalon2->device_data;
1060  	int temp = get_current_temp_max(info);
1061  	float volts = (float)info->set_voltage / 10000;
1062  
1063  	tailsprintf(buf, bufsiz, "%4dMhz %2dC %3d%% %.3fV", info->set_frequency,
1064  		    temp, info->fan_pct, volts);
1065  }
1066  
1067  static void avalon2_shutdown(struct thr_info *thr)
1068  {
1069  	struct cgpu_info *avalon2 = thr->cgpu;
1070  	int interface = usb_interface(avalon2);
1071  
1072  	usb_transfer(avalon2, PL2303_CTRL_OUT, PL2303_REQUEST_CTRL, 0, interface, C_SETLINE);
1073  }
1074  
1075  struct device_drv avalon2_drv = {
1076  	.drv_id = DRIVER_avalon2,
1077  	.dname = "avalon2",
1078  	.name = "AV2",
1079  	.get_api_stats = avalon2_api_stats,
1080  	.get_statline_before = avalon2_statline_before,
1081  	.drv_detect = avalon2_detect,
1082  	.thread_prepare = avalon2_prepare,
1083  	.hash_work = hash_driver_work,
1084  	.flush_work = avalon2_update,
1085  	.update_work = avalon2_update,
1086  	.scanwork = avalon2_scanhash,
1087  	.thread_shutdown = avalon2_shutdown,
1088  };