Browse Source

avalon: Replace avalon-options with set_device_funcs

Luke Dashjr 12 years ago
parent
commit
ca39930d13
3 changed files with 114 additions and 127 deletions
  1. 86 122
      driver-avalon.c
  2. 2 0
      driver-avalon.h
  3. 26 5
      miner.c

+ 86 - 122
driver-avalon.c

@@ -45,8 +45,6 @@
 
 BFG_REGISTER_DRIVER(avalon_drv)
 
-static int option_offset = -1;
-
 static int avalon_init_task(struct avalon_task *at,
 			    uint8_t reset, uint8_t ff, uint8_t fan,
 			    uint8_t timeout, uint8_t asic_num,
@@ -419,119 +417,80 @@ static void avalon_idle(struct cgpu_info *avalon)
 	applog(LOG_ERR, "Avalon: Goto idle mode");
 }
 
-static void get_options(int this_option_offset, int *baud, int *miner_count,
-			int *asic_count, int *timeout, int *frequency)
+static
+const char *avalon_set_baud(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
 {
-	char buf[BUFSIZ+1];
-	char *ptr, *comma, *colon, *colon2, *colon3, *colon4;
-	size_t max;
-	int i, tmp;
-
-	if (opt_avalon_options == NULL)
-		buf[0] = '\0';
-	else {
-		ptr = opt_avalon_options;
-		for (i = 0; i < this_option_offset; i++) {
-			comma = strchr(ptr, ',');
-			if (comma == NULL)
-				break;
-			ptr = comma + 1;
-		}
-
-		comma = strchr(ptr, ',');
-		if (comma == NULL)
-			max = strlen(ptr);
-		else
-			max = comma - ptr;
-
-		if (max > BUFSIZ)
-			max = BUFSIZ;
-		strncpy(buf, ptr, max);
-		buf[max] = '\0';
-	}
-
-	*baud = AVALON_IO_SPEED;
-	*miner_count = AVALON_DEFAULT_MINER_NUM - 8;
-	*asic_count = AVALON_DEFAULT_ASIC_NUM;
-	*timeout = AVALON_DEFAULT_TIMEOUT;
-	*frequency = AVALON_DEFAULT_FREQUENCY;
+	struct avalon_info * const info = proc->device_data;
+	const int baud = atoi(newvalue);
+	if (!valid_baud(baud))
+		return "Invalid baud setting";
+	info->baud = baud;
+	return NULL;
+}
 
-	if (!(*buf))
-		return;
+static
+const char *avalon_set_miner_count(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
+{
+	struct avalon_info * const info = proc->device_data;
+	const int miner_count = atoi(newvalue);
+	if (miner_count <= 0 || miner_count > AVALON_DEFAULT_MINER_NUM)
+		return "Invalid miner_count: must be 1 ~ " AVALON_DEFAULT_MINER_NUM_S;
+	info->miner_count = miner_count;
+	return NULL;
+}
 
-	colon = strchr(buf, ':');
-	if (colon)
-		*(colon++) = '\0';
-
-	tmp = atoi(buf);
-	if (!valid_baud(*baud = tmp))
-		quit(1, "Invalid avalon-options for baud (%s)", buf);
-
-	if (colon && *colon) {
-		colon2 = strchr(colon, ':');
-		if (colon2)
-			*(colon2++) = '\0';
-
-		if (*colon) {
-			tmp = atoi(colon);
-			if (tmp > 0 && tmp <= AVALON_DEFAULT_MINER_NUM) {
-				*miner_count = tmp;
-			} else {
-				quit(1, "Invalid avalon-options for "
-					"miner_count (%s) must be 1 ~ %d",
-					colon, AVALON_DEFAULT_MINER_NUM);
-			}
-		}
+static
+const char *avalon_set_asic_count(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
+{
+	struct avalon_info * const info = proc->device_data;
+	const int asic_count = atoi(newvalue);
+	if (asic_count <= 0 || asic_count > AVALON_DEFAULT_ASIC_NUM)
+		return "Invalid asic_count: must be 1 ~ " AVALON_DEFAULT_ASIC_NUM_S;
+	info->asic_count = asic_count;
+	return NULL;
+}
 
-		if (colon2 && *colon2) {
-			colon3 = strchr(colon2, ':');
-			if (colon3)
-				*(colon3++) = '\0';
-
-			tmp = atoi(colon2);
-			if (tmp > 0 && tmp <= AVALON_DEFAULT_ASIC_NUM)
-				*asic_count = tmp;
-			else {
-				quit(1, "Invalid avalon-options for "
-					"asic_count (%s) must be 1 ~ %d",
-					colon2, AVALON_DEFAULT_ASIC_NUM);
-			}
+static
+const char *avalon_set_timeout(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
+{
+	struct avalon_info * const info = proc->device_data;
+	const int timeout = atoi(newvalue);
+	if (timeout <= 0 || timeout > 0xff)
+		return "Invalid timeout: must be 1 ~ 255";
+	info->timeout = timeout;
+	return NULL;
+}
 
-			if (colon3 && *colon3) {
-				colon4 = strchr(colon3, ':');
-				if (colon4)
-					*(colon4++) = '\0';
-
-				tmp = atoi(colon3);
-				if (tmp > 0 && tmp <= 0xff)
-					*timeout = tmp;
-				else {
-					quit(1, "Invalid avalon-options for "
-						"timeout (%s) must be 1 ~ %d",
-						colon3, 0xff);
-				}
-				if (colon4 && *colon4) {
-					tmp = atoi(colon4);
-					switch (tmp) {
-					case 256:
-					case 270:
-					case 282:
-					case 300:
-					case 325:
-					case 350:
-					case 375:
-						*frequency = tmp;
-						break;
-					default:
-						quit(1, "Invalid avalon-options for "
-							"frequency must be 256/270/282/300/325/350/375");
-					}
-				}
-			}
-		}
+static
+const char *avalon_set_clock(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
+{
+	struct avalon_info * const info = proc->device_data;
+	const int clock = atoi(newvalue);
+	switch (clock) {
+		default:
+			return "Invalid clock: must be 256/270/282/300/325/350/375";
+		case 256:
+		case 270:
+		case 282:
+		case 300:
+		case 325:
+		case 350:
+		case 375:
+			info->frequency = clock;
 	}
+	return NULL;
 }
 
+const struct bfg_set_device_definition avalon_set_device_funcs[] = {
+	// NOTE: Order of parameters below is important for --avalon-options
+	{"baud"       , avalon_set_baud       , "serial baud rate"},
+	{"miner_count", avalon_set_miner_count, ""},
+	{"asic_count" , avalon_set_asic_count , ""},
+	{"timeout"    , avalon_set_timeout    , "how long the device will work on a work item before accepting new work"},
+	{"clock"      , avalon_set_clock      , "clock speed: 256, 270, 282, 300, 325, 350, or 375"},
+	{NULL},
+};
+
 /* Non blocking clearing of anything in the buffer */
 static void avalon_clear_readbuf(int fd)
 {
@@ -559,23 +518,31 @@ static bool avalon_detect_one(const char *devpath)
 	struct avalon_info *info;
 	struct avalon_result ar;
 	int fd, ret;
-	int baud, miner_count, asic_count, timeout, frequency = 0;
 	struct cgpu_info *avalon;
 
 	if (serial_claim(devpath, &avalon_drv))
 		return false;
 	
-	int this_option_offset = ++option_offset;
-	get_options(this_option_offset, &baud, &miner_count, &asic_count,
-		    &timeout, &frequency);
+	info = malloc(sizeof(*info));
+	if (unlikely(!info))
+		applogr(false, LOG_ERR, "Failed to malloc avalon_info data");
+	*info = (struct avalon_info){
+		.baud = AVALON_IO_SPEED,
+		.miner_count = AVALON_DEFAULT_MINER_NUM - 8,
+		.asic_count = AVALON_DEFAULT_ASIC_NUM,
+		.timeout = AVALON_DEFAULT_TIMEOUT,
+		.frequency = AVALON_DEFAULT_FREQUENCY,
+	};
+	drv_set_defaults2(&avalon_drv, avalon_set_device_funcs, info);
 
 	applog(LOG_DEBUG, "Avalon Detect: Attempting to open %s "
 	       "(baud=%d miner_count=%d asic_count=%d timeout=%d frequency=%d)",
-	       devpath, baud, miner_count, asic_count, timeout, frequency);
+	       devpath, info->baud, info->miner_count, info->asic_count, info->timeout, info->frequency);
 
-	fd = avalon_open2(devpath, baud, true);
+	fd = avalon_open2(devpath, info->baud, true);
 	if (unlikely(fd == -1)) {
 		applog(LOG_ERR, "Avalon Detect: Failed to open %s", devpath);
+		free(info);
 		return false;
 	}
 	avalon_clear_readbuf(fd);
@@ -586,27 +553,22 @@ static bool avalon_detect_one(const char *devpath)
 	avalon->device_path = strdup(devpath);
 	avalon->device_fd = fd;
 	avalon->threads = AVALON_MINER_THREADS;
+	avalon->set_device_funcs = avalon_set_device_funcs;
 	add_cgpu(avalon);
 
 	ret = avalon_reset(fd, &ar);
 	if (ret) {
 		; /* FIXME: I think IT IS avalon and wait on reset;
 		   * avalon_close(fd);
+		   * free(info);
 		   * return false; */
 	}
 	
 	applog(LOG_INFO, "Avalon Detect: Found at %s, mark as %d",
 	       devpath, avalon->device_id);
 
-	avalon->device_data = calloc(sizeof(struct avalon_info), 1);
-	if (unlikely(!(avalon->device_data)))
-		quit(1, "Failed to malloc avalon_info data");
-	info = avalon->device_data;
+	avalon->device_data = info;
 
-	info->baud = baud;
-	info->miner_count = miner_count;
-	info->asic_count = asic_count;
-	info->timeout = timeout;
 	info->read_count = ((float)info->timeout * AVALON_HASH_TIME_FACTOR *
 			    AVALON_TIME_FACTOR) / (float)info->miner_count;
 
@@ -620,7 +582,6 @@ static bool avalon_detect_one(const char *devpath)
 	info->temp_history_index = 0;
 	info->temp_sum = 0;
 	info->temp_old = 0;
-	info->frequency = frequency;
 
 	/* Set asic to idle mode after detect */
 	avalon_idle(avalon);
@@ -646,6 +607,9 @@ static void avalon_init(struct cgpu_info *avalon)
 	struct avalon_info *info = avalon->device_data;
 	struct avalon_result ar;
 	int fd, ret;
+	
+	cgpu_set_defaults(avalon);
+	avalon->set_device_funcs = NULL;
 
 	avalon->device_fd = -1;
 	fd = avalon_open(avalon->device_path, info->baud);

+ 2 - 0
driver-avalon.h

@@ -30,7 +30,9 @@
 #define AVALON_DEFAULT_TIMEOUT 0x32
 #define AVALON_DEFAULT_FREQUENCY 256
 #define AVALON_DEFAULT_MINER_NUM 0x20
+#define AVALON_DEFAULT_MINER_NUM_S "32"
 #define AVALON_DEFAULT_ASIC_NUM 0xA
+#define AVALON_DEFAULT_ASIC_NUM_S "10"
 
 #define AVALON_FTDI_READSIZE 512
 

+ 26 - 5
miner.c

@@ -216,9 +216,6 @@ bool opt_disable_pool;
 static bool no_work;
 bool opt_worktime;
 bool opt_weighed_stats;
-#ifdef USE_AVALON
-char *opt_avalon_options = NULL;
-#endif
 
 char *opt_kernel_path;
 char *cgminer_path;
@@ -1742,10 +1739,34 @@ static char *set_icarus_timing(const char *arg)
 #endif
 
 #ifdef USE_AVALON
+extern const struct bfg_set_device_definition avalon_set_device_funcs[];
+
 static char *set_avalon_options(const char *arg)
 {
-	opt_set_charp(arg, &opt_avalon_options);
-
+	if (strchr(arg, ','))
+		return "avalon-options no longer supports comma-delimited syntax, see README.FPGA for better control";
+	applog(LOG_WARNING, "avalon-options is deprecated! See README.FPGA for better control");
+	
+	char *opts = strdup(arg), *argdup;
+	argdup = opts;
+	const struct bfg_set_device_definition *sdf = avalon_set_device_funcs;
+	char buf[0x100], *saveptr, *opt;
+	for (int i = 0; i < 5; ++i, ++sdf)
+	{
+		opt = strtok_r(opts, ":", &saveptr);
+		opts = NULL;
+		
+		if (!opt)
+			break;
+		
+		if (!opt[0])
+			continue;
+		
+		snprintf(buf, sizeof(buf), "avalon:%s=%s", sdf->optname, opt);
+		applog(LOG_DEBUG, "%s: Using --set-device %s", __func__, buf);
+		string_elist_add(buf, &opt_set_device_list);
+	}
+	free(argdup);
 	return NULL;
 }
 #endif