Commit 73343f38bc29afb9a4bbe57d2f283a88f2a5027c

Angus Gratton 2013-12-09T11:39:03

Merge remote-tracking branch 'upstream' into merge_upstream Conflicts: usbutils.c

diff --git a/api.c b/api.c
index c82b0d2..108bda1 100644
--- a/api.c
+++ b/api.c
@@ -4278,7 +4278,7 @@ static void mcast()
 
 		count++;
 		came_from_siz = sizeof(came_from);
-		if (SOCKETFAIL(rep = recvfrom(mcast_sock, buf, sizeof(buf),
+		if (SOCKETFAIL(rep = recvfrom(mcast_sock, buf, sizeof(buf) - 1,
 						0, (struct sockaddr *)(&came_from), &came_from_siz))) {
 			applog(LOG_DEBUG, "API mcast failed count=%d (%s) (%d)",
 					count, SOCKERRMSG, (int)mcast_sock);
diff --git a/cgminer.c b/cgminer.c
index a36a3cb..10c6aa1 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -77,6 +77,7 @@ char *curly = ":D";
 int opt_hfa_ntime_roll;
 int opt_hfa_hash_clock;
 bool opt_hfa_pll_bypass;
+bool opt_hfa_dfu_boot;
 #endif
 
 #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_AVALON) || defined(USE_MODMINER)
@@ -210,12 +211,6 @@ int hotplug_time = 5;
 pthread_mutex_t lockstat_lock;
 #endif
 
-#ifdef USE_USBUTILS
-pthread_mutex_t cgusb_lock;
-pthread_mutex_t cgusbres_lock;
-cglock_t cgusb_fd_lock;
-#endif
-
 pthread_mutex_t hash_lock;
 static pthread_mutex_t *stgd_lock;
 pthread_mutex_t console_lock;
@@ -1211,12 +1206,15 @@ static struct opt_table opt_config_table[] = {
 		     "Override avalon-options for BitBurner Fury boards baud:miners:asic:timeout:freq"),
 #endif
 #ifdef USE_HASHFAST
-	OPT_WITH_ARG("--hfa-ntime-roll",
-		     opt_set_intval, NULL, &opt_hfa_ntime_roll,
-		     opt_hidden),
+	OPT_WITHOUT_ARG("--hfa-dfu-boot",
+			opt_set_bool, &opt_hfa_dfu_boot,
+			opt_hidden),
 	OPT_WITH_ARG("--hfa-hash-clock",
 		     opt_set_intval, NULL, &opt_hfa_hash_clock,
 		     opt_hidden),
+	OPT_WITH_ARG("--hfa-ntime-roll",
+		     opt_set_intval, NULL, &opt_hfa_ntime_roll,
+		     opt_hidden),
 	OPT_WITHOUT_ARG("--hfa-pll-bypass",
 			opt_set_bool, &opt_hfa_pll_bypass,
 			opt_hidden),
@@ -7838,14 +7836,13 @@ static void *libusb_poll_thread(void __maybe_unused *arg)
 
 static void initialise_usb(void) {
 	int err = libusb_init(NULL);
+
 	if (err) {
 		fprintf(stderr, "libusb_init() failed err %d", err);
 		fflush(stderr);
 		quit(1, "libusb_init() failed");
 	}
-	mutex_init(&cgusb_lock);
-	mutex_init(&cgusbres_lock);
-	cglock_init(&cgusb_fd_lock);
+	initialise_usblocks();
 	usb_polling = true;
 	pthread_create(&usb_poll_thread, NULL, libusb_poll_thread, NULL);
 }
diff --git a/driver-hashfast.c b/driver-hashfast.c
index f77b259..fefe57d 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -84,7 +84,7 @@ static const struct hfa_cmd hfa_cmds[] = {
 	{OP_GET_TRACE, "OP_GET_TRACE", C_NULL},
 	{OP_LOOPBACK_USB, "OP_LOOPBACK_USB", C_NULL},
 	{OP_LOOPBACK_UART, "OP_LOOPBACK_UART", C_NULL},
-	{OP_DFU, "OP_DFU", C_NULL},
+	{OP_DFU, "OP_DFU", C_HF_DFU},
 	{OP_USB_SHUTDOWN, "OP_USB_SHUTDOWN", C_NULL},
 	{OP_DIE_STATUS, "OP_DIE_STATUS", C_HF_DIE_STATUS},	// 24
 	{OP_GWQ_STATUS, "OP_GWQ_STATUS", C_HF_GWQ_STATUS},
@@ -240,10 +240,7 @@ static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
 	hu->operation_code = OP_USB_INIT;
 	hu->protocol = PROTOCOL_GLOBAL_WORK_QUEUE;	// Protocol to use
 	// Force PLL bypass
-	if (opt_hfa_pll_bypass) {
-		hu->user_configuration = 1;
-		hu->pll_bypass = 1;
-	}
+	hu->pll_bypass = opt_hfa_pll_bypass;
 	hu->hash_clock = info->hash_clock_rate;		// Hash clock rate in Mhz
 	if (info->group_ntime_roll > 1 && info->core_ntime_roll) {
 		ho = (struct hf_usb_init_options *)(hu + 1);
@@ -433,6 +430,15 @@ static bool hfa_initialise(struct cgpu_info *hashfast)
 	return (err == 7);
 }
 
+static void hfa_dfu_boot(struct cgpu_info *hashfast)
+{
+	bool ret;
+
+	ret = hfa_send_frame(hashfast, HF_USB_CMD(OP_DFU), 0, NULL, 0);
+	applog(LOG_WARNING, "HFA %d %03d:%03d DFU Boot %s", hashfast->device_id, hashfast->usbinfo.bus_number,
+	       hashfast->usbinfo.device_address, ret ? "Succeeded" : "Failed");
+}
+
 static struct cgpu_info *hfa_detect_one(libusb_device *dev, struct usb_find_devices *found)
 {
 	struct cgpu_info *hashfast;
@@ -452,7 +458,11 @@ static struct cgpu_info *hfa_detect_one(libusb_device *dev, struct usb_find_devi
 		hashfast = usb_free_cgpu(hashfast);
 		return NULL;
 	}
-
+	if (opt_hfa_dfu_boot) {
+		hfa_dfu_boot(hashfast);
+		hashfast = usb_free_cgpu(hashfast);
+		return NULL;
+	}
 	if (!hfa_detect_common(hashfast)) {
 		usb_uninit(hashfast);
 		hashfast = usb_free_cgpu(hashfast);
diff --git a/driver-hashfast.h b/driver-hashfast.h
index 5ce7234..c6cc46e 100644
--- a/driver-hashfast.h
+++ b/driver-hashfast.h
@@ -19,6 +19,8 @@
 int opt_hfa_ntime_roll;
 int opt_hfa_hash_clock;
 bool opt_hfa_pll_bypass;
+bool opt_hfa_dfu_boot;
+
 #define HASHFAST_MINER_THREADS 1
 
 // Matching fields for hf_statistics, but large #s for local accumulation, per-die
diff --git a/miner.h b/miner.h
index 94e60d9..d67a955 100644
--- a/miner.h
+++ b/miner.h
@@ -1053,12 +1053,6 @@ extern int opt_queue;
 extern int opt_scantime;
 extern int opt_expiry;
 
-#ifdef USE_USBUTILS
-extern pthread_mutex_t cgusb_lock;
-extern pthread_mutex_t cgusbres_lock;
-extern cglock_t cgusb_fd_lock;
-#endif
-
 extern cglock_t control_lock;
 extern pthread_mutex_t hash_lock;
 extern pthread_mutex_t console_lock;
diff --git a/usbutils.c b/usbutils.c
index e1251ff..86db57d 100644
--- a/usbutils.c
+++ b/usbutils.c
@@ -18,6 +18,10 @@
 #include "miner.h"
 #include "usbutils.h"
 
+static pthread_mutex_t cgusb_lock;
+static pthread_mutex_t cgusbres_lock;
+static cglock_t cgusb_fd_lock;
+
 #define NODEV(err) ((err) != LIBUSB_SUCCESS && (err) != LIBUSB_ERROR_TIMEOUT)
 
 #define NOCONTROLDEV(err) ((err) < 0 && NODEV(err))
@@ -2458,13 +2462,13 @@ static int usb_submit_transfer(struct usb_transfer *ut, struct libusb_transfer *
 }
 
 static int
-usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
-		  int epinfo, unsigned char *data, int length,
-		  int *transferred, unsigned int timeout,
-		  struct cgpu_info *cgpu, __maybe_unused int mode,
-		  enum usb_cmds cmd, __maybe_unused int seq, bool cancellable)
+usb_bulk_transfer(struct cgpu_info *cgpu, struct cg_usb_device *usbdev, int intinfo,
+		  int epinfo, unsigned char *data, int length, int *transferred,
+		  unsigned int timeout, __maybe_unused int mode, enum usb_cmds cmd,
+		  __maybe_unused int seq, bool cancellable)
 {
 	int bulk_timeout, callback_timeout = timeout, pipe_retries = 0;
+	struct libusb_device_handle *dev_handle = usbdev->handle;
 	struct usb_epinfo *usb_epinfo;
 	struct usb_transfer ut;
 	unsigned char endpoint;
@@ -2483,7 +2487,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
 	bulk_timeout = 0;
 #endif
 
-	usb_epinfo = &(cgpu->usbdev->found->intinfos[intinfo].epinfos[epinfo]);
+	usb_epinfo = &(usbdev->found->intinfos[intinfo].epinfos[epinfo]);
 	endpoint = usb_epinfo->ep;
 
 	/* Avoid any async transfers during shutdown to allow the polling
@@ -2606,10 +2610,9 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t
 	initial_timeout = timeout;
 	cgtime(&read_start);
 	while (bufleft > 0 && !eom) {
-		err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
-					ptr, usbbufread, &got, timeout,
-					cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1,
-					cancellable);
+		err = usb_bulk_transfer(cgpu, usbdev, intinfo, epinfo, ptr, usbbufread,
+					&got, timeout, MODE_BULK_READ, cmd,
+					first ? SEQ0 : SEQ1, cancellable);
 		cgtime(&tv_finish);
 		ptr[got] = '\0';
 
@@ -2690,10 +2693,10 @@ out_noerrmsg:
 
 int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, int timeout, enum usb_cmds cmd)
 {
-	struct cg_usb_device *usbdev;
 	struct timeval write_start, tv_finish;
+	bool first = true, usb11 = false;
+	struct cg_usb_device *usbdev;
 	unsigned int initial_timeout;
-	__maybe_unused bool first = true;
 	int err, sent, tot, pstate;
 	double done;
 
@@ -2711,6 +2714,8 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_
 	}
 
 	usbdev = cgpu->usbdev;
+	if (usbdev->descriptor->bcdUSB < 0x0200)
+		usb11 = true;
 	if (timeout == DEVTIMEOUT)
 		timeout = usbdev->found->timeout;
 
@@ -2724,7 +2729,7 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_
 		/* USB 1.1 devices don't handle zero packets well so split them
 		 * up to not have the final transfer equal to the wMaxPacketSize
 		 * or they will stall waiting for more data. */
-		if (usbdev->descriptor->bcdUSB < 0x0200) {
+		if (usb11) {
 			struct usb_epinfo *ue = &usbdev->found->intinfos[intinfo].epinfos[epinfo];
 
 			if (tosend == ue->wMaxPacketSize) {
@@ -2733,10 +2738,9 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_
 					tosend = 1;
 			}
 		}
-		err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
-					(unsigned char *)buf, tosend, &sent, timeout,
-					cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1,
-					false);
+		err = usb_bulk_transfer(cgpu, usbdev, intinfo, epinfo, (unsigned char *)buf,
+					tosend, &sent, timeout, MODE_BULK_WRITE,
+					cmd, first ? SEQ0 : SEQ1, false);
 		cgtime(&tv_finish);
 
 		USBDEBUG("USB debug: @_usb_write(%s (nodev=%s)) err=%d%s sent=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), sent);
@@ -3595,6 +3599,7 @@ fila:
 	free(sem);
 	free(key);
 	remove_in_use(bus_number, device_address);
+	unlink(name);
 	return;
 #endif
 }
@@ -3663,3 +3668,10 @@ void *usb_resource_thread(void __maybe_unused *userdata)
 
 	return NULL;
 }
+
+void initialise_usblocks(void)
+{
+	mutex_init(&cgusb_lock);
+	mutex_init(&cgusbres_lock);
+	cglock_init(&cgusb_fd_lock);
+}
diff --git a/usbutils.h b/usbutils.h
index 4b0e6fc..d2565f0 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -377,6 +377,7 @@ struct cg_usb_info {
 	USB_ADD_COMMAND(C_HF_STATISTICS, "HFStatistics") \
 	USB_ADD_COMMAND(C_HF_CLOCKGATE, "HFClockGate") \
 	USB_ADD_COMMAND(C_HF_USB_INIT, "HFUSBInit") \
+	USB_ADD_COMMAND(C_HF_DFU, "HFDFU") \
 	USB_ADD_COMMAND(C_HF_DIE_STATUS, "HFDieStatus") \
 	USB_ADD_COMMAND(C_HF_GWQ_STATUS, "HFGWQStatus") \
 	USB_ADD_COMMAND(C_HF_WORK_RESTART, "HFWorkRestart") \
@@ -425,6 +426,7 @@ void usb_set_dev_start(struct cgpu_info *cgpu);
 void usb_cleanup();
 void usb_initialise();
 void *usb_resource_thread(void *userdata);
+void initialise_usblocks(void);
 
 #define usb_read(cgpu, buf, bufsiz, read, cmd) \
 	_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false, false)