Commit c5694ee82a20172ea88aa092c98cb3e0071adc88

Con Kolivas 2014-02-14T21:23:42

Add the ability to whitelist previously blacklisted usb devices from the menu.

diff --git a/cgminer.c b/cgminer.c
index 88212be..4d8f0b3 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -5150,7 +5150,7 @@ static void mt_enable(struct thr_info *mythr)
 
 static void set_usb(void)
 {
-	int selected, i, mt, enabled = 0, disabled = 0, zombie = 0, total = 0;
+	int selected, i, mt, enabled, disabled, zombie, total, blacklisted;
 	struct cgpu_info *cgpu;
 	struct thr_info *thr;
 	double val;
@@ -5161,6 +5161,12 @@ static void set_usb(void)
 	clear_logwin();
 
 retry:
+	enabled = 0;
+	disabled = 0;
+	zombie = 0;
+	total = 0;
+	blacklisted = 0;
+
 	rd_lock(&mining_thr_lock);
 	mt = mining_threads;
 	rd_unlock(&mining_thr_lock);
@@ -5175,6 +5181,8 @@ retry:
 			disabled++;
 		else
 			enabled++;
+		if (cgpu->blacklisted)
+			blacklisted++;
 		total++;
 	}
 	wlogprint("Hotplug interval:%d\n", hotplug_time);
@@ -5186,7 +5194,8 @@ retry:
 	wlogprint("[U]nplug to allow hotplug restart\n");
 	wlogprint("[R]eset device USB\n");
 	wlogprint("[L]ist all known devices\n");
-	wlogprint("[B]lacklist current device from cgminer\n");
+	wlogprint("[B]lacklist current device from current instance of cgminer\n");
+	wlogprint("[W]hitelist previously blacklisted device\n");
 	wlogprint("Select an option or any other key to return\n");
 	logwin_update();
 	input = getch();
@@ -5287,6 +5296,34 @@ retry:
 		}
 		blacklist_cgpu(cgpu);
 		goto retry;
+	} else if (!strncasecmp(&input, "w", 1)) {
+		if (!blacklisted) {
+			wlogprint("No blacklisted devices!\n");
+			goto retry;
+		}
+		wlogprint("Blacklisted devices:\n");
+		for (i = 0; i < mt; i++) {
+			cgpu = mining_thr[i]->cgpu;
+			if (unlikely(!cgpu))
+				continue;
+			if (cgpu->blacklisted) {
+				wlogprint("%d: %s %d %03u:%03u\n", i, cgpu->drv->name,
+					  cgpu->device_id, cgpu->usbinfo.bus_number,
+					  cgpu->usbinfo.device_address);
+			}
+		}
+		selected = curses_int("Select device number");
+		if (selected < 0 || selected >= mt)  {
+			wlogprint("Invalid selection\n");
+			goto retry;
+		}
+		cgpu = mining_thr[selected]->cgpu;
+		if (!cgpu->blacklisted) {
+			wlogprint("Device not blacklisted, unable to whitelist\n");
+			goto retry;
+		}
+		whitelist_cgpu(cgpu);
+		goto retry;
 	} else if (!strncasecmp(&input, "l", 1)) {
 		usb_all(0);
 		goto retry;
diff --git a/usbutils.c b/usbutils.c
index be300d0..bb4c997 100644
--- a/usbutils.c
+++ b/usbutils.c
@@ -1304,22 +1304,26 @@ nofway:
 				(int)bus_number, (int)device_address);
 }
 
-static void remove_in_use(uint8_t bus_number, uint8_t device_address)
+static void __remove_in_use(uint8_t bus_number, uint8_t device_address, bool blacklist)
 {
-	struct usb_in_use_list *in_use_tmp;
+	struct usb_in_use_list *in_use_tmp, **head;
 	bool found = false;
 
 	mutex_lock(&cgusb_lock);
+	if (blacklist)
+		head = &blacklist_head;
+	else
+		head = &in_use_head;
 
-	in_use_tmp = in_use_head;
+	in_use_tmp = *head;
 	while (in_use_tmp) {
 		if (in_use_tmp->in_use.bus_number == (int)bus_number &&
 		    in_use_tmp->in_use.device_address == (int)device_address) {
 			found = true;
-			if (in_use_tmp == in_use_head) {
-				in_use_head = in_use_head->next;
-				if (in_use_head)
-					in_use_head->prev = NULL;
+			if (in_use_tmp == *head) {
+				*head = (*head)->next;
+				if (*head)
+					(*head)->prev = NULL;
 			} else {
 				in_use_tmp->prev->next = in_use_tmp->next;
 				if (in_use_tmp->next)
@@ -1338,6 +1342,11 @@ static void remove_in_use(uint8_t bus_number, uint8_t device_address)
 				(int)bus_number, (int)device_address);
 }
 
+static void remove_in_use(uint8_t bus_number, uint8_t device_address)
+{
+	__remove_in_use(bus_number, device_address, false);
+}
+
 static bool cgminer_usb_lock_bd(struct device_drv *drv, uint8_t bus_number, uint8_t device_address)
 {
 	struct resource_work *res_work;
@@ -1545,12 +1554,24 @@ static void release_cgpu(struct cgpu_info *cgpu)
 
 void blacklist_cgpu(struct cgpu_info *cgpu)
 {
-	if (cgpu->blacklisted)
+	if (cgpu->blacklisted) {
+		applog(LOG_WARNING, "Device already blacklisted");
 		return;
+	}
+	cgpu->blacklisted = true;
+	add_in_use(cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address, true);
 	if (__release_cgpu(cgpu))
 		cgminer_usb_unlock_bd(cgpu->drv, cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address);
-	add_in_use(cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address, true);
-	cgpu->blacklisted = true;
+}
+
+void whitelist_cgpu(struct cgpu_info *cgpu)
+{
+	if (!cgpu->blacklisted) {
+		applog(LOG_WARNING, "Device not blacklisted");
+		return;
+	}
+	__remove_in_use(cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address, true);
+	cgpu->blacklisted = false;
 }
 
 /*
diff --git a/usbutils.h b/usbutils.h
index 5802943..c92d64d 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -421,6 +421,7 @@ void usb_all(int level);
 const char *usb_cmdname(enum usb_cmds cmd);
 void usb_applog(struct cgpu_info *cgpu, enum usb_cmds cmd, char *msg, int amount, int err);
 void blacklist_cgpu(struct cgpu_info *cgpu);
+void whitelist_cgpu(struct cgpu_info *cgpu);
 void usb_nodev(struct cgpu_info *cgpu);
 struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig);
 struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads);