Browse Source

kncasic: Split up each ASIC channel to its own device

Luke Dashjr 11 years ago
parent
commit
57ba4bf5c6
1 changed files with 33 additions and 26 deletions
  1. 33 26
      driver-kncasic.c

+ 33 - 26
driver-kncasic.c

@@ -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;
 }
 }