Browse Source

icarus: Support disabling reopen quirk via --icarus-options

Luke Dashjr 13 years ago
parent
commit
bbb834ad72
2 changed files with 28 additions and 5 deletions
  1. 7 3
      FPGA-README
  2. 21 2
      driver-icarus.c

+ 7 - 3
FPGA-README

@@ -42,7 +42,7 @@ Icarus
 There are two hidden options in cgminer when Icarus support is compiled in:
 There are two hidden options in cgminer when Icarus support is compiled in:
 
 
 --icarus-options <arg> Set specific FPGA board configurations - one set of values for all or comma separated
 --icarus-options <arg> Set specific FPGA board configurations - one set of values for all or comma separated
-           baud:work_division:fpga_count
+           baud:work_division:fpga_count:quirks
 
 
            baud           The Serial/USB baud rate - 115200 or 57600 only - default 115200
            baud           The Serial/USB baud rate - 115200 or 57600 only - default 115200
            work_division  The fraction of work divided up for each FPGA chip - 1, 2, 4 or 8
            work_division  The fraction of work divided up for each FPGA chip - 1, 2, 4 or 8
@@ -51,13 +51,17 @@ There are two hidden options in cgminer when Icarus support is compiled in:
                           as work_division - range is from 1 up to 'work_division'
                           as work_division - range is from 1 up to 'work_division'
                           It defaults to the value of work_division - or 2 if you don't specify
                           It defaults to the value of work_division - or 2 if you don't specify
                           work_division
                           work_division
+           quirks         List of quirks to enable and disable (after a minus sign):
+                            r  Reopen device regularly to workaround buggy Icarus USB chipset
+                               (enabled by default)
 
 
 If you define fewer comma seperated values than Icarus devices, the last values will be used
 If you define fewer comma seperated values than Icarus devices, the last values will be used
 for all extra devices
 for all extra devices
 
 
-An example would be: --icarus-options 57600:2:1
+An example would be: --icarus-options 57600:2:1:-r
 This would mean: use 57600 baud, the FPGA board divides the work in half however
 This would mean: use 57600 baud, the FPGA board divides the work in half however
-only 1 FPGA actually runs on the board (e.g. like an early CM1 Icarus copy bitstream)
+only 1 FPGA actually runs on the board, and don't reopen the device (e.g. like
+an early CM1 Icarus copy bitstream)
 
 
 --icarus-timing <arg> Set how the Icarus timing is calculated - one setting/value for all or comma separated
 --icarus-timing <arg> Set how the Icarus timing is calculated - one setting/value for all or comma separated
            default[=N]   Use the default Icarus hash time (2.6316ns)
            default[=N]   Use the default Icarus hash time (2.6316ns)

+ 21 - 2
driver-icarus.c

@@ -190,6 +190,7 @@ struct ICARUS_INFO {
 	int work_division;
 	int work_division;
 	int fpga_count;
 	int fpga_count;
 	uint32_t nonce_mask;
 	uint32_t nonce_mask;
+	bool quirk_reopen;
 };
 };
 
 
 #define END_CONDITION 0x0000ffff
 #define END_CONDITION 0x0000ffff
@@ -459,7 +460,7 @@ static uint32_t mask(int work_division)
 	return nonce_mask;
 	return nonce_mask;
 }
 }
 
 
-static void get_options(int this_option_offset, int *baud, int *work_division, int *fpga_count)
+static void get_options(int this_option_offset, int *baud, int *work_division, int *fpga_count, char **quirkstr)
 {
 {
 	char err_buf[BUFSIZ+1];
 	char err_buf[BUFSIZ+1];
 	char buf[BUFSIZ+1];
 	char buf[BUFSIZ+1];
@@ -467,6 +468,7 @@ static void get_options(int this_option_offset, int *baud, int *work_division, i
 	size_t max;
 	size_t max;
 	int i, tmp;
 	int i, tmp;
 
 
+	*quirkstr = "";
 	if (opt_icarus_options == NULL)
 	if (opt_icarus_options == NULL)
 		buf[0] = '\0';
 		buf[0] = '\0';
 	else {
 	else {
@@ -531,6 +533,11 @@ static void get_options(int this_option_offset, int *baud, int *work_division, i
 			}
 			}
 
 
 			if (colon2 && *colon2) {
 			if (colon2 && *colon2) {
+			  colon = strchr(colon2, ':');
+			  if (colon)
+					*(colon++) = '\0';
+
+			  if (*colon2) {
 				tmp = atoi(colon2);
 				tmp = atoi(colon2);
 				if (tmp > 0 && tmp <= *work_division)
 				if (tmp > 0 && tmp <= *work_division)
 					*fpga_count = tmp;
 					*fpga_count = tmp;
@@ -538,6 +545,11 @@ static void get_options(int this_option_offset, int *baud, int *work_division, i
 					sprintf(err_buf, "Invalid icarus-options for fpga_count (%s) must be >0 and <=work_division (%d)", colon2, *work_division);
 					sprintf(err_buf, "Invalid icarus-options for fpga_count (%s) must be >0 and <=work_division (%d)", colon2, *work_division);
 					quit(1, err_buf);
 					quit(1, err_buf);
 				}
 				}
+			  }
+
+			  if (colon && *colon) {
+					*quirkstr = colon;
+			  }
 			}
 			}
 		}
 		}
 	}
 	}
@@ -574,8 +586,9 @@ static bool icarus_detect_one(const char *devpath)
 	char *nonce_hex;
 	char *nonce_hex;
 
 
 	int baud, work_division, fpga_count;
 	int baud, work_division, fpga_count;
+	char *quirkstr;
 
 
-	get_options(this_option_offset, &baud, &work_division, &fpga_count);
+	get_options(this_option_offset, &baud, &work_division, &fpga_count, &quirkstr);
 
 
 	applog(LOG_DEBUG, "Icarus Detect: Attempting to open %s", devpath);
 	applog(LOG_DEBUG, "Icarus Detect: Attempting to open %s", devpath);
 
 
@@ -645,6 +658,8 @@ static bool icarus_detect_one(const char *devpath)
 	info->work_division = work_division;
 	info->work_division = work_division;
 	info->fpga_count = fpga_count;
 	info->fpga_count = fpga_count;
 	info->nonce_mask = mask(work_division);
 	info->nonce_mask = mask(work_division);
+	quirkstr = strchr(quirkstr, '-');
+	info->quirk_reopen = quirkstr ? !strchr(quirkstr, 'r') : true;
 
 
 	info->golden_hashes = (golden_nonce_val & info->nonce_mask) * fpga_count;
 	info->golden_hashes = (golden_nonce_val & info->nonce_mask) * fpga_count;
 	timersub(&tv_finish, &tv_start, &(info->golden_tv));
 	timersub(&tv_finish, &tv_start, &(info->golden_tv));
@@ -784,6 +799,8 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 		}
 		}
 	}
 	}
 
 
+	if (info->quirk_reopen) {
+
 	// Reopen the serial port to workaround a USB-host-chipset-specific issue with the Icarus's buggy USB-UART
 	// Reopen the serial port to workaround a USB-host-chipset-specific issue with the Icarus's buggy USB-UART
 	icarus_close(fd);
 	icarus_close(fd);
 	fd = icarus_open(icarus->device_path, icarus_info[icarus->device_id]->baud);
 	fd = icarus_open(icarus->device_path, icarus_info[icarus->device_id]->baud);
@@ -794,6 +811,8 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 	}
 	}
 	icarus->device_fd = fd;
 	icarus->device_fd = fd;
 
 
+	}
+
 	work->blk.nonce = 0xffffffff;
 	work->blk.nonce = 0xffffffff;
 
 
 	if (state->firstrun) {
 	if (state->firstrun) {