|
@@ -1,7 +1,6 @@
|
|
|
/*
|
|
/*
|
|
|
- * cgminer driver for KnCminer devices
|
|
|
|
|
- *
|
|
|
|
|
* Copyright 2014 KnCminer
|
|
* Copyright 2014 KnCminer
|
|
|
|
|
+ * Copyright 2014 Luke Dashjr
|
|
|
*
|
|
*
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
@@ -99,7 +98,6 @@ struct knc_die {
|
|
|
#define KNC_SPI_BUFFERS (3)
|
|
#define KNC_SPI_BUFFERS (3)
|
|
|
|
|
|
|
|
struct knc_state {
|
|
struct knc_state {
|
|
|
- struct cgpu_info *cgpu;
|
|
|
|
|
void *ctx;
|
|
void *ctx;
|
|
|
int generation; /* work/block generation, incremented on each flush invalidating older works */
|
|
int generation; /* work/block generation, incremented on each flush invalidating older works */
|
|
|
int dies;
|
|
int dies;
|
|
@@ -252,7 +250,6 @@ static bool knc_detect_one(void *ctx)
|
|
|
{
|
|
{
|
|
|
/* Scan device for ASICs */
|
|
/* Scan device for ASICs */
|
|
|
int channel, die, cores = 0, core;
|
|
int channel, die, cores = 0, core;
|
|
|
- struct cgpu_info *cgpu;
|
|
|
|
|
struct knc_state *knc;
|
|
struct knc_state *knc;
|
|
|
struct knc_die_info die_info[KNC_MAX_ASICS][KNC_MAX_DIES_PER_ASIC];
|
|
struct knc_die_info die_info[KNC_MAX_ASICS][KNC_MAX_DIES_PER_ASIC];
|
|
|
|
|
|
|
@@ -275,22 +272,25 @@ static bool knc_detect_one(void *ctx)
|
|
|
|
|
|
|
|
applog(LOG_ERR, "Found a KnC miner with %d cores", cores);
|
|
applog(LOG_ERR, "Found a KnC miner with %d cores", cores);
|
|
|
|
|
|
|
|
- cgpu = calloc(1, sizeof(*cgpu));
|
|
|
|
|
knc = calloc(1, sizeof(*knc) + cores * sizeof(struct knc_core_state));
|
|
knc = calloc(1, sizeof(*knc) + cores * sizeof(struct knc_core_state));
|
|
|
- if (!cgpu || !knc) {
|
|
|
|
|
|
|
+ if (!knc)
|
|
|
|
|
+ {
|
|
|
applog(LOG_ERR, "KnC miner detected, but failed to allocate memory");
|
|
applog(LOG_ERR, "KnC miner detected, but failed to allocate memory");
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- knc->cgpu = cgpu;
|
|
|
|
|
knc->ctx = ctx;
|
|
knc->ctx = ctx;
|
|
|
knc->generation = 1;
|
|
knc->generation = 1;
|
|
|
|
|
|
|
|
/* Index all cores */
|
|
/* Index all cores */
|
|
|
|
|
+ struct cgpu_info *prev_cgpu = NULL, *first_cgpu;
|
|
|
int dies = 0;
|
|
int dies = 0;
|
|
|
cores = 0;
|
|
cores = 0;
|
|
|
struct knc_core_state *pcore = knc->core;
|
|
struct knc_core_state *pcore = knc->core;
|
|
|
|
|
+ int channel_cores_base = 0;
|
|
|
for (channel = 0; channel < KNC_MAX_ASICS; channel++) {
|
|
for (channel = 0; channel < KNC_MAX_ASICS; channel++) {
|
|
|
|
|
+ int channel_cores = 0;
|
|
|
|
|
+
|
|
|
for (die = 0; die < KNC_MAX_DIES_PER_ASIC; die++) {
|
|
for (die = 0; die < KNC_MAX_DIES_PER_ASIC; die++) {
|
|
|
if (die_info[channel][die].cores) {
|
|
if (die_info[channel][die].cores) {
|
|
|
knc->die[dies].channel = channel;
|
|
knc->die[dies].channel = channel;
|
|
@@ -304,42 +304,49 @@ static bool knc_detect_one(void *ctx)
|
|
|
knc->die[dies].core[core].core = core;
|
|
knc->die[dies].core[core].core = core;
|
|
|
}
|
|
}
|
|
|
cores += knc->die[dies].cores;
|
|
cores += knc->die[dies].cores;
|
|
|
|
|
+ channel_cores += knc->die[dies].cores;
|
|
|
pcore += knc->die[dies].cores;
|
|
pcore += knc->die[dies].cores;
|
|
|
dies++;
|
|
dies++;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if (channel_cores)
|
|
|
|
|
+ {
|
|
|
|
|
+ struct cgpu_info * const cgpu = malloc(sizeof(*cgpu));
|
|
|
|
|
+ *cgpu = (struct cgpu_info){
|
|
|
|
|
+ .drv = &kncasic_drv,
|
|
|
|
|
+ .name = "KnCminer",
|
|
|
|
|
+ .procs = channel_cores,
|
|
|
|
|
+ .threads = prev_cgpu ? 0 : 1,
|
|
|
|
|
+ .device_data = knc,
|
|
|
|
|
+ };
|
|
|
|
|
+ add_cgpu_slave(cgpu, prev_cgpu);
|
|
|
|
|
+ if (!prev_cgpu)
|
|
|
|
|
+ first_cgpu = cgpu;
|
|
|
|
|
+ prev_cgpu = cgpu;
|
|
|
|
|
+
|
|
|
|
|
+ for_each_managed_proc(proc, cgpu)
|
|
|
|
|
+ {
|
|
|
|
|
+ knc->core[channel_cores_base++].proc = proc;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
knc->dies = dies;
|
|
knc->dies = dies;
|
|
|
knc->cores = cores;
|
|
knc->cores = cores;
|
|
|
knc->startup = 2;
|
|
knc->startup = 2;
|
|
|
|
|
|
|
|
- cgpu->drv = &kncasic_drv;
|
|
|
|
|
- cgpu->name = "KnCminer";
|
|
|
|
|
- cgpu->procs = cores;
|
|
|
|
|
- cgpu->threads = 1;
|
|
|
|
|
-
|
|
|
|
|
- cgpu->device_data = knc;
|
|
|
|
|
-
|
|
|
|
|
pthread_mutex_init(&knc->spi_qlock, NULL);
|
|
pthread_mutex_init(&knc->spi_qlock, NULL);
|
|
|
pthread_cond_init(&knc->spi_qcond, NULL);
|
|
pthread_cond_init(&knc->spi_qcond, NULL);
|
|
|
pthread_mutex_init(&knc->state_lock, NULL);
|
|
pthread_mutex_init(&knc->state_lock, NULL);
|
|
|
|
|
|
|
|
- if (thr_info_create(&knc->spi_thr, NULL, knc_spi, (void *)cgpu)) {
|
|
|
|
|
- applog(LOG_ERR, "%s%i: SPI thread create failed",
|
|
|
|
|
- cgpu->drv->name, cgpu->device_id);
|
|
|
|
|
- free(cgpu);
|
|
|
|
|
|
|
+ if (thr_info_create(&knc->spi_thr, NULL, knc_spi, first_cgpu))
|
|
|
|
|
+ {
|
|
|
|
|
+ applog(LOG_ERR, "%s: SPI thread create failed", first_cgpu->dev_repr);
|
|
|
free(knc);
|
|
free(knc);
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- add_cgpu(cgpu);
|
|
|
|
|
-
|
|
|
|
|
- core = 0;
|
|
|
|
|
- for_each_managed_proc(proc, cgpu)
|
|
|
|
|
- {
|
|
|
|
|
- knc->core[core++].proc = proc;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|