1
0
mirror of https://github.com/GOSTSec/sgminer synced 2025-01-22 20:44:19 +00:00

usbutils hotplug v0.1

This commit is contained in:
Kano 2013-02-02 09:51:47 +11:00
parent 296eab26b4
commit 983fe2b0c0
5 changed files with 255 additions and 42 deletions

59
api.c
View File

@ -1148,6 +1148,7 @@ static int numpgas()
int count = 0; int count = 0;
int i; int i;
mutex_lock(&devices_lock);
for (i = 0; i < total_devices; i++) { for (i = 0; i < total_devices; i++) {
#ifdef USE_BITFORCE #ifdef USE_BITFORCE
if (devices[i]->drv->drv_id == DRIVER_BITFORCE) if (devices[i]->drv->drv_id == DRIVER_BITFORCE)
@ -1166,6 +1167,7 @@ static int numpgas()
count++; count++;
#endif #endif
} }
mutex_unlock(&devices_lock);
return count; return count;
} }
@ -1174,6 +1176,7 @@ static int pgadevice(int pgaid)
int count = 0; int count = 0;
int i; int i;
mutex_lock(&devices_lock);
for (i = 0; i < total_devices; i++) { for (i = 0; i < total_devices; i++) {
#ifdef USE_BITFORCE #ifdef USE_BITFORCE
if (devices[i]->drv->drv_id == DRIVER_BITFORCE) if (devices[i]->drv->drv_id == DRIVER_BITFORCE)
@ -1191,9 +1194,12 @@ static int pgadevice(int pgaid)
if (devices[i]->drv->drv_id == DRIVER_MODMINER) if (devices[i]->drv->drv_id == DRIVER_MODMINER)
count++; count++;
#endif #endif
if (count == (pgaid + 1)) if (count == (pgaid + 1)) {
mutex_unlock(&devices_lock);
return i; return i;
}
} }
mutex_unlock(&devices_lock);
return -1; return -1;
} }
#endif #endif
@ -1527,9 +1533,14 @@ static void pgastatus(struct io_data *io_data, int pga, bool isjson, bool precom
if (dev < 0) // Should never happen if (dev < 0) // Should never happen
return; return;
struct cgpu_info *cgpu = devices[dev]; struct cgpu_info *cgpu;
double frequency = 0; double frequency = 0;
float temp = cgpu->temp; float temp;
mutex_lock(&devices_lock);
cgpu = devices[dev];
mutex_unlock(&devices_lock);
temp = cgpu->temp;
#ifdef USE_ZTEX #ifdef USE_ZTEX
if (cgpu->drv->drv_id == DRIVER_ZTEX && cgpu->device_ztex) if (cgpu->drv->drv_id == DRIVER_ZTEX && cgpu->device_ztex)
@ -1747,6 +1758,7 @@ static void pgadev(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *p
static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{ {
struct cgpu_info *cgpu;
int numpga = numpgas(); int numpga = numpgas();
struct thr_info *thr; struct thr_info *thr;
int pga; int pga;
@ -1775,7 +1787,9 @@ static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char
return; return;
} }
struct cgpu_info *cgpu = devices[dev]; mutex_lock(&devices_lock);
cgpu = devices[dev];
mutex_unlock(&devices_lock);
applog(LOG_DEBUG, "API: request to pgaenable pgaid %d device %d %s%u", applog(LOG_DEBUG, "API: request to pgaenable pgaid %d device %d %s%u",
id, dev, cgpu->drv->name, cgpu->device_id); id, dev, cgpu->drv->name, cgpu->device_id);
@ -1814,6 +1828,7 @@ static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char
static void pgadisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) static void pgadisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{ {
struct cgpu_info *cgpu;
int numpga = numpgas(); int numpga = numpgas();
int id; int id;
@ -1839,7 +1854,9 @@ static void pgadisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, cha
return; return;
} }
struct cgpu_info *cgpu = devices[dev]; mutex_lock(&devices_lock);
cgpu = devices[dev];
mutex_unlock(&devices_lock);
applog(LOG_DEBUG, "API: request to pgadisable pgaid %d device %d %s%u", applog(LOG_DEBUG, "API: request to pgadisable pgaid %d device %d %s%u",
id, dev, cgpu->drv->name, cgpu->device_id); id, dev, cgpu->drv->name, cgpu->device_id);
@ -1856,6 +1873,8 @@ static void pgadisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, cha
static void pgaidentify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) static void pgaidentify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
{ {
struct cgpu_info *cgpu;
struct device_drv *drv;
int numpga = numpgas(); int numpga = numpgas();
int id; int id;
@ -1881,8 +1900,10 @@ static void pgaidentify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, ch
return; return;
} }
struct cgpu_info *cgpu = devices[dev]; mutex_lock(&devices_lock);
struct device_drv *drv = cgpu->drv; cgpu = devices[dev];
mutex_unlock(&devices_lock);
drv = cgpu->drv;
if (!drv->identify_device) if (!drv->identify_device)
message(io_data, MSG_PGANOID, id, NULL, isjson); message(io_data, MSG_PGANOID, id, NULL, isjson);
@ -2794,6 +2815,7 @@ void notifystatus(struct io_data *io_data, int device, struct cgpu_info *cgpu, b
static void notify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, char group) static void notify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, char group)
{ {
struct cgpu_info *cgpu;
bool io_open = false; bool io_open = false;
int i; int i;
@ -2807,8 +2829,12 @@ static void notify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe
if (isjson) if (isjson)
io_open = io_add(io_data, COMSTR JSON_NOTIFY); io_open = io_add(io_data, COMSTR JSON_NOTIFY);
for (i = 0; i < total_devices; i++) for (i = 0; i < total_devices; i++) {
notifystatus(io_data, i, devices[i], isjson, group); mutex_lock(&devices_lock);
cgpu = devices[i];
mutex_unlock(&devices_lock);
notifystatus(io_data, i, cgpu, isjson, group);
}
if (isjson && io_open) if (isjson && io_open)
io_close(io_data); io_close(io_data);
@ -2833,7 +2859,9 @@ static void devdetails(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
io_open = io_add(io_data, COMSTR JSON_DEVDETAILS); io_open = io_add(io_data, COMSTR JSON_DEVDETAILS);
for (i = 0; i < total_devices; i++) { for (i = 0; i < total_devices; i++) {
mutex_lock(&devices_lock);
cgpu = devices[i]; cgpu = devices[i];
mutex_unlock(&devices_lock);
root = api_add_int(root, "DEVDETAILS", &i, false); root = api_add_int(root, "DEVDETAILS", &i, false);
root = api_add_string(root, "Name", cgpu->drv->name, false); root = api_add_string(root, "Name", cgpu->drv->name, false);
@ -2930,6 +2958,7 @@ static int itemstats(struct io_data *io_data, int i, char *id, struct cgminer_st
static void minerstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) static void minerstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
{ {
struct cgpu_info *cgpu;
bool io_open = false; bool io_open = false;
struct api_data *extra; struct api_data *extra;
char id[20]; char id[20];
@ -2942,7 +2971,9 @@ static void minerstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
i = 0; i = 0;
for (j = 0; j < total_devices; j++) { for (j = 0; j < total_devices; j++) {
struct cgpu_info *cgpu = devices[j]; mutex_lock(&devices_lock);
cgpu = devices[j];
mutex_unlock(&devices_lock);
if (cgpu && cgpu->drv) { if (cgpu && cgpu->drv) {
if (cgpu->drv->get_api_stats) if (cgpu->drv->get_api_stats)
@ -3182,6 +3213,8 @@ static void usbstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __may
#ifdef HAVE_AN_FPGA #ifdef HAVE_AN_FPGA
static void pgaset(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) static void pgaset(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
{ {
struct cgpu_info *cgpu;
struct device_drv *drv;
char buf[TMPBUFSIZ]; char buf[TMPBUFSIZ];
int numpga = numpgas(); int numpga = numpgas();
@ -3215,8 +3248,10 @@ static void pgaset(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe
return; return;
} }
struct cgpu_info *cgpu = devices[dev]; mutex_lock(&devices_lock);
struct device_drv *drv = cgpu->drv; cgpu = devices[dev];
mutex_unlock(&devices_lock);
drv = cgpu->drv;
char *set = strchr(opt, ','); char *set = strchr(opt, ',');
if (set) if (set)

201
cgminer.c
View File

@ -157,7 +157,14 @@ static int input_thr_id;
#endif #endif
int gpur_thr_id; int gpur_thr_id;
static int api_thr_id; static int api_thr_id;
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
static int hotplug_thr_id;
#endif
static int total_control_threads; static int total_control_threads;
bool hotplug_mode;
static int new_devices;
static int new_threads;
static int start_devices;
#ifdef HAVE_LIBUSB #ifdef HAVE_LIBUSB
pthread_mutex_t cgusb_lock; pthread_mutex_t cgusb_lock;
@ -173,6 +180,7 @@ static pthread_mutex_t sshare_lock;
pthread_rwlock_t netacc_lock; pthread_rwlock_t netacc_lock;
pthread_mutex_t mining_thr_lock; pthread_mutex_t mining_thr_lock;
pthread_mutex_t devices_lock;
static pthread_mutex_t lp_lock; static pthread_mutex_t lp_lock;
static pthread_cond_t lp_cond; static pthread_cond_t lp_cond;
@ -742,18 +750,24 @@ static void load_temp_cutoffs()
if (val < 0 || val > 200) if (val < 0 || val > 200)
quit(1, "Invalid value passed to set temp cutoff"); quit(1, "Invalid value passed to set temp cutoff");
mutex_lock(&devices_lock);
devices[device]->cutofftemp = val; devices[device]->cutofftemp = val;
mutex_unlock(&devices_lock);
} }
} else { } else {
mutex_lock(&devices_lock);
for (i = device; i < total_devices; ++i) { for (i = device; i < total_devices; ++i) {
if (!devices[i]->cutofftemp) if (!devices[i]->cutofftemp)
devices[i]->cutofftemp = opt_cutofftemp; devices[i]->cutofftemp = opt_cutofftemp;
} }
mutex_unlock(&devices_lock);
return; return;
} }
if (device <= 1) { if (device <= 1) {
mutex_lock(&devices_lock);
for (i = device; i < total_devices; ++i) for (i = device; i < total_devices; ++i)
devices[i]->cutofftemp = val; devices[i]->cutofftemp = val;
mutex_unlock(&devices_lock);
} }
} }
@ -1990,9 +2004,12 @@ static void curses_print_devstatus(int thr_id)
char displayed_hashes[16], displayed_rolling[16]; char displayed_hashes[16], displayed_rolling[16];
uint64_t dh64, dr64; uint64_t dh64, dr64;
if (opt_compact)
return;
cgpu = get_thr_cgpu(thr_id); cgpu = get_thr_cgpu(thr_id);
if (devcursor + cgpu->cgminer_id > LINES - 2 || opt_compact) if (cgpu->cgminer_id >= start_devices || devcursor + cgpu->cgminer_id > LINES - 2)
return; return;
cgpu->utility = cgpu->accepted / total_secs * 60; cgpu->utility = cgpu->accepted / total_secs * 60;
@ -2782,6 +2799,16 @@ static void __kill_work(void)
applog(LOG_INFO, "Received kill message"); applog(LOG_INFO, "Received kill message");
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
/* Best to get rid of it first so it doesn't
* try to create any new devices */
if (!opt_scrypt) {
applog(LOG_DEBUG, "Killing off HotPlug thread");
thr = &control_thr[hotplug_thr_id];
thr_info_cancel(thr);
}
#endif
applog(LOG_DEBUG, "Killing off watchpool thread"); applog(LOG_DEBUG, "Killing off watchpool thread");
/* Kill the watchpool thread */ /* Kill the watchpool thread */
thr = &control_thr[watchpool_thr_id]; thr = &control_thr[watchpool_thr_id];
@ -4015,10 +4042,14 @@ void zero_stats(void)
zero_bestshare(); zero_bestshare();
mutex_lock(&hash_lock);
for (i = 0; i < total_devices; ++i) { for (i = 0; i < total_devices; ++i) {
struct cgpu_info *cgpu = devices[i]; struct cgpu_info *cgpu;
mutex_lock(&devices_lock);
cgpu = devices[i];
mutex_unlock(&devices_lock);
mutex_lock(&hash_lock);
cgpu->total_mhashes = 0; cgpu->total_mhashes = 0;
cgpu->accepted = 0; cgpu->accepted = 0;
cgpu->rejected = 0; cgpu->rejected = 0;
@ -4029,8 +4060,8 @@ void zero_stats(void)
cgpu->diff_accepted = 0; cgpu->diff_accepted = 0;
cgpu->diff_rejected = 0; cgpu->diff_rejected = 0;
cgpu->last_share_diff = 0; cgpu->last_share_diff = 0;
mutex_unlock(&hash_lock);
} }
mutex_unlock(&hash_lock);
} }
#ifdef HAVE_CURSES #ifdef HAVE_CURSES
@ -5936,12 +5967,17 @@ static void *watchdog_thread(void __maybe_unused *userdata)
} }
for (i = 0; i < total_devices; ++i) { for (i = 0; i < total_devices; ++i) {
struct cgpu_info *cgpu = devices[i]; struct cgpu_info *cgpu;
struct thr_info *thr = cgpu->thr[0]; struct thr_info *thr;
enum dev_enable *denable; enum dev_enable *denable;
char dev_str[8]; char dev_str[8];
int gpu; int gpu;
mutex_lock(&devices_lock);
cgpu = devices[i];
mutex_unlock(&devices_lock);
thr = cgpu->thr[0];
if (cgpu->drv->get_stats) if (cgpu->drv->get_stats)
cgpu->drv->get_stats(cgpu); cgpu->drv->get_stats(cgpu);
@ -6104,8 +6140,13 @@ void print_summary(void)
} }
applog(LOG_WARNING, "Summary of per device statistics:\n"); applog(LOG_WARNING, "Summary of per device statistics:\n");
for (i = 0; i < total_devices; ++i) for (i = 0; i < total_devices; ++i) {
log_print_status(devices[i]); struct cgpu_info *cgpu;
mutex_lock(&devices_lock);
cgpu = devices[i];
mutex_unlock(&devices_lock);
log_print_status(cgpu);
}
if (opt_shares) if (opt_shares)
applog(LOG_WARNING, "Mined %d accepted shares of %d requested\n", total_accepted, opt_shares); applog(LOG_WARNING, "Mined %d accepted shares of %d requested\n", total_accepted, opt_shares);
@ -6355,7 +6396,7 @@ void enable_curses(void) {
} }
#endif #endif
/* TODO: fix need a dummy CPU device_api even if no support for CPU mining */ /* TODO: fix need a dummy CPU device_drv even if no support for CPU mining */
#ifndef WANT_CPUMINE #ifndef WANT_CPUMINE
struct device_drv cpu_drv; struct device_drv cpu_drv;
struct device_drv cpu_drv = { struct device_drv cpu_drv = {
@ -6386,11 +6427,18 @@ static int cgminer_id_count = 0;
void enable_device(struct cgpu_info *cgpu) void enable_device(struct cgpu_info *cgpu)
{ {
cgpu->deven = DEV_ENABLED; cgpu->deven = DEV_ENABLED;
mutex_lock(&devices_lock);
devices[cgpu->cgminer_id = cgminer_id_count++] = cgpu; devices[cgpu->cgminer_id = cgminer_id_count++] = cgpu;
mining_threads += cgpu->threads; mutex_unlock(&devices_lock);
if (hotplug_mode) {
new_threads += cgpu->threads;
adj_width(mining_threads + new_threads, &dev_width);
} else {
mining_threads += cgpu->threads;
#ifdef HAVE_CURSES #ifdef HAVE_CURSES
adj_width(mining_threads, &dev_width); adj_width(mining_threads, &dev_width);
#endif #endif
}
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
if (cgpu->drv->drv_id == DRIVER_OPENCL) { if (cgpu->drv->drv_id == DRIVER_OPENCL) {
gpu_threads += cgpu->threads; gpu_threads += cgpu->threads;
@ -6418,8 +6466,13 @@ bool add_cgpu(struct cgpu_info*cgpu)
cgpu->device_id = d->lastid = 0; cgpu->device_id = d->lastid = 0;
HASH_ADD_STR(devids, name, d); HASH_ADD_STR(devids, name, d);
} }
devices = realloc(devices, sizeof(struct cgpu_info *) * (total_devices + 2)); mutex_lock(&devices_lock);
devices[total_devices++] = cgpu; devices = realloc(devices, sizeof(struct cgpu_info *) * (total_devices + new_devices + 2));
mutex_unlock(&devices_lock);
if (hotplug_mode)
devices[total_devices + new_devices++] = cgpu;
else
devices[total_devices++] = cgpu;
return true; return true;
} }
@ -6438,6 +6491,105 @@ struct device_drv *copy_drv(struct device_drv *drv)
return copy; return copy;
} }
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
static void hotplug_process()
{
struct thr_info *thr;
int i, j;
for (i = 0; i < new_devices; i++) {
struct cgpu_info *cgpu = devices[total_devices + i];
enable_device(cgpu);
cgpu->cgminer_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;
cgpu->rolling = cgpu->total_mhashes = 0;
}
mutex_lock(&mining_thr_lock);
mining_thr = realloc(mining_thr, sizeof(thr) * (mining_threads + new_threads + 1));
mutex_unlock(&mining_thr_lock);
if (!mining_thr)
quit(1, "Failed to hotplug realloc mining_thr");
for (i = 0; i < new_threads; i++) {
mining_thr[mining_threads + i] = calloc(1, sizeof(*thr));
if (!mining_thr[mining_threads + i])
quit(1, "Failed to hotplug calloc mining_thr[%d]", i);
}
// Start threads
for (i = 0; i < new_devices; ++i) {
struct cgpu_info *cgpu = devices[total_devices];
cgpu->thr = malloc(sizeof(*cgpu->thr) * (cgpu->threads+1));
cgpu->thr[cgpu->threads] = NULL;
cgpu->status = LIFE_INIT;
for (j = 0; j < cgpu->threads; ++j) {
mutex_lock(&mining_thr_lock);
thr = mining_thr[mining_threads];
mutex_unlock(&mining_thr_lock);
thr->id = mining_threads;
thr->cgpu = cgpu;
thr->device_thread = j;
thr->q = tq_new();
if (!thr->q)
quit(1, "tq_new hotplug failed in starting %s%d mining thread (#%d)", cgpu->drv->name, cgpu->device_id, total_devices);
/* Enable threads for devices set not to mine but disable
* their queue in case we wish to enable them later */
if (cgpu->deven != DEV_DISABLED) {
applog(LOG_DEBUG, "Pushing hotplug ping to thread %d", thr->id);
tq_push(thr->q, &ping);
}
if (cgpu->drv->thread_prepare && !cgpu->drv->thread_prepare(thr))
continue;
thread_reportout(thr);
if (unlikely(thr_info_create(thr, NULL, miner_thread, thr)))
quit(1, "hotplug thread %d create failed", thr->id);
cgpu->thr[j] = thr;
mining_threads++;
}
total_devices++;
applog(LOG_WARNING, "Hotplug: %s added %s %i", cgpu->drv->dname, cgpu->drv->name, cgpu->device_id);
}
}
static void *hotplug_thread(void __maybe_unused *userdata)
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
RenameThread("hotplug");
hotplug_mode = true;
while (0x2a) {
sleep(5);
// Version 0.1 just add the devices on - worry about using nodev later
new_devices = 0;
new_threads = 0;
#ifdef USE_BITFORCE
bitforce_drv.drv_detect();
#endif
#ifdef USE_MODMINER
modminer_drv.drv_detect();
#endif
if (new_devices)
hotplug_process();
}
return NULL;
}
#endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
bool pools_active = false; bool pools_active = false;
@ -6479,6 +6631,7 @@ int main(int argc, char *argv[])
rwlock_init(&blk_lock); rwlock_init(&blk_lock);
rwlock_init(&netacc_lock); rwlock_init(&netacc_lock);
mutex_init(&mining_thr_lock); mutex_init(&mining_thr_lock);
mutex_init(&devices_lock);
mutex_init(&lp_lock); mutex_init(&lp_lock);
if (unlikely(pthread_cond_init(&lp_cond, NULL))) if (unlikely(pthread_cond_init(&lp_cond, NULL)))
@ -6714,6 +6867,8 @@ int main(int argc, char *argv[])
if (!total_devices) if (!total_devices)
quit(1, "All devices disabled, cannot mine!"); quit(1, "All devices disabled, cannot mine!");
start_devices = total_devices;
load_temp_cutoffs(); load_temp_cutoffs();
for (i = 0; i < total_devices; ++i) for (i = 0; i < total_devices; ++i)
@ -6772,7 +6927,7 @@ int main(int argc, char *argv[])
quit(1, "Failed to calloc mining_thr[%d]", i); quit(1, "Failed to calloc mining_thr[%d]", i);
} }
total_control_threads = 7; total_control_threads = 8;
control_thr = calloc(total_control_threads, sizeof(*thr)); control_thr = calloc(total_control_threads, sizeof(*thr));
if (!control_thr) if (!control_thr)
quit(1, "Failed to calloc control_thr"); quit(1, "Failed to calloc control_thr");
@ -6947,11 +7102,21 @@ begin_bench:
if (thr_info_create(thr, NULL, api_thread, thr)) if (thr_info_create(thr, NULL, api_thread, thr))
quit(1, "API thread create failed"); quit(1, "API thread create failed");
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
if (!opt_scrypt) {
hotplug_thr_id = 6;
thr = &control_thr[hotplug_thr_id];
if (thr_info_create(thr, NULL, hotplug_thread, thr))
quit(1, "hotplug thread create failed");
pthread_detach(thr->pth);
}
#endif
#ifdef HAVE_CURSES #ifdef HAVE_CURSES
/* Create curses input thread for keyboard input. Create this last so /* Create curses input thread for keyboard input. Create this last so
* that we know all threads are created since this can call kill_work * that we know all threads are created since this can call kill_work
* to try and shut down ll previous threads. */ * to try and shut down all previous threads. */
input_thr_id = 6; input_thr_id = 7;
thr = &control_thr[input_thr_id]; thr = &control_thr[input_thr_id];
if (thr_info_create(thr, NULL, input_thread, thr)) if (thr_info_create(thr, NULL, input_thread, thr))
quit(1, "input thread create failed"); quit(1, "input thread create failed");
@ -6959,8 +7124,8 @@ begin_bench:
#endif #endif
/* Just to be sure */ /* Just to be sure */
if (total_control_threads != 7) if (total_control_threads != 8)
quit(1, "incorrect total_control_threads (%d) should be 7", total_control_threads); quit(1, "incorrect total_control_threads (%d) should be 8", total_control_threads);
/* Once everything is set up, main() becomes the getwork scheduler */ /* Once everything is set up, main() becomes the getwork scheduler */
while (42) { while (42) {

View File

@ -390,7 +390,9 @@ static void ztex_shutdown(struct thr_info *thr)
static void ztex_disable(struct thr_info *thr) static void ztex_disable(struct thr_info *thr)
{ {
applog(LOG_ERR, "%s: Disabling!", thr->cgpu->device_ztex->repr); applog(LOG_ERR, "%s: Disabling!", thr->cgpu->device_ztex->repr);
mutex_lock(&devices_lock);
devices[thr->cgpu->device_id]->deven = DEV_DISABLED; devices[thr->cgpu->device_id]->deven = DEV_DISABLED;
mutex_unlock(&devices_lock);
ztex_shutdown(thr); ztex_shutdown(thr);
} }

View File

@ -738,6 +738,7 @@ extern pthread_mutex_t hash_lock;
extern pthread_mutex_t console_lock; extern pthread_mutex_t console_lock;
extern pthread_mutex_t ch_lock; extern pthread_mutex_t ch_lock;
extern pthread_mutex_t mining_thr_lock; extern pthread_mutex_t mining_thr_lock;
extern pthread_mutex_t devices_lock;
extern pthread_mutex_t restart_lock; extern pthread_mutex_t restart_lock;
extern pthread_cond_t restart_cond; extern pthread_cond_t restart_cond;
@ -778,6 +779,7 @@ extern void add_pool_details(struct pool *pool, bool live, char *url, char *user
#define _MAX_INTENSITY_STR "14" #define _MAX_INTENSITY_STR "14"
#endif #endif
extern bool hotplug_mode;
extern struct list_head scan_devices; extern struct list_head scan_devices;
extern int nDevs; extern int nDevs;
extern int opt_n_threads; extern int opt_n_threads;

View File

@ -624,7 +624,9 @@ static bool cgminer_usb_lock_bd(struct device_drv *drv, uint8_t bus_number, uint
case WAIT_ABANDONED: case WAIT_ABANDONED:
// Am I using it already? // Am I using it already?
for (i = 0; i < total_devices; i++) { for (i = 0; i < total_devices; i++) {
mutex_lock(&devices_lock);
cgpu = devices[i]; cgpu = devices[i];
mutex_unlock(&devices_lock);
if (cgpu->usbinfo.bus_number == bus_number && if (cgpu->usbinfo.bus_number == bus_number &&
cgpu->usbinfo.device_address == device_address && cgpu->usbinfo.device_address == device_address &&
cgpu->usbinfo.nodev == false) { cgpu->usbinfo.nodev == false) {
@ -642,9 +644,10 @@ static bool cgminer_usb_lock_bd(struct device_drv *drv, uint8_t bus_number, uint
} }
return true; return true;
case WAIT_TIMEOUT: case WAIT_TIMEOUT:
applog(LOG_WARNING, if (!hotplug_mode)
"MTX: %s USB failed to get '%s' - device in use", applog(LOG_WARNING,
drv->dname, name); "MTX: %s USB failed to get '%s' - device in use",
drv->dname, name);
goto fail; goto fail;
case WAIT_FAILED: case WAIT_FAILED:
applog(LOG_ERR, applog(LOG_ERR,
@ -726,9 +729,10 @@ fail:
if (semop(sem, sops, 2)) { if (semop(sem, sops, 2)) {
if (errno == EAGAIN) { if (errno == EAGAIN) {
applog(LOG_WARNING, if (!hotplug_mode)
"SEM: %s USB failed to get (%d) '%s' - device in use", applog(LOG_WARNING,
drv->dname, sem, name); "SEM: %s USB failed to get (%d) '%s' - device in use",
drv->dname, sem, name);
} else { } else {
applog(LOG_DEBUG, applog(LOG_DEBUG,
"SEM: %s USB failed to get (%d) '%s' err (%d) %s", "SEM: %s USB failed to get (%d) '%s' err (%d) %s",
@ -849,6 +853,7 @@ void usb_uninit(struct cgpu_info *cgpu)
void release_cgpu(struct cgpu_info *cgpu) void release_cgpu(struct cgpu_info *cgpu)
{ {
struct cg_usb_device *cgusb = cgpu->usbdev; struct cg_usb_device *cgusb = cgpu->usbdev;
struct cgpu_info *lookcgpu;
int i; int i;
cgpu->usbinfo.nodev = true; cgpu->usbinfo.nodev = true;
@ -857,14 +862,18 @@ void release_cgpu(struct cgpu_info *cgpu)
// Any devices sharing the same USB device should be marked also // Any devices sharing the same USB device should be marked also
// Currently only MMQ shares a USB device // Currently only MMQ shares a USB device
for (i = 0; i < total_devices; i++) for (i = 0; i < total_devices; i++) {
if (devices[i] != cgpu && devices[i]->usbdev == cgusb) { mutex_lock(&devices_lock);
devices[i]->usbinfo.nodev = true; lookcgpu = devices[i];
devices[i]->usbinfo.nodev_count++; mutex_unlock(&devices_lock);
memcpy(&(devices[i]->usbinfo.last_nodev), if (lookcgpu != cgpu && lookcgpu->usbdev == cgusb) {
lookcgpu->usbinfo.nodev = true;
lookcgpu->usbinfo.nodev_count++;
memcpy(&(lookcgpu->usbinfo.last_nodev),
&(cgpu->usbinfo.last_nodev), sizeof(struct timeval)); &(cgpu->usbinfo.last_nodev), sizeof(struct timeval));
devices[i]->usbdev = NULL; lookcgpu->usbdev = NULL;
} }
}
usb_uninit(cgpu); usb_uninit(cgpu);