Switch to async SPI transfer model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
diff --git a/driver-knc.c b/driver-knc.c
index 0e49ee2..a360c11 100644
--- a/driver-knc.c
+++ b/driver-knc.c
@@ -56,6 +56,7 @@ struct knc_die;
struct knc_core_state {
int generation;
int core;
+ int coreid;
struct knc_die *die;
struct {
int slot;
@@ -129,9 +130,11 @@ struct knc_state {
int request_length;
int response_length;
enum {
- KNC_MESSAGE_UNKNOWN = 0,
- KNC_MESSAGE_REPORT,
- KNC_MESSAGE_INFO
+ KNC_UNKNOWN = 0,
+ KNC_NO_RESPONSE,
+ KNC_SETWORK,
+ KNC_REPORT,
+ KNC_INFO
} type;
uint32_t data;
int offset;
@@ -279,10 +282,11 @@ static bool knc_detect_one(void *ctx)
cores += knc->die[dies].cores;
pcore += knc->die[dies].cores;
dies++;
-
}
}
}
+ for (core = 0; core < cores; core++)
+ knc->core[core].coreid = core;
knc->dies = dies;
knc->cores = cores;
knc->startup = 2;
@@ -436,7 +440,8 @@ static void knc_spi_process_responses(struct thr_info *thr)
uint8_t *rxbuf = &buffer->rxbuf[response_info->offset];
int status = knc_decode_response(rxbuf, response_info->request_length, &rxbuf, response_info->response_length);
switch(response_info->type) {
- case KNC_MESSAGE_REPORT:
+ case KNC_REPORT:
+ case KNC_SETWORK:
knc_core_process_report(thr, &knc->core[response_info->data], rxbuf);
break;
}
@@ -457,7 +462,7 @@ static void knc_spi_process_responses(struct thr_info *thr)
}
-static int knc_core_send_work(struct thr_info *thr, int coreid, struct knc_core_state *core, struct work *work, bool clean)
+static int knc_core_send_work(struct thr_info *thr, struct knc_core_state *core, struct work *work, bool clean)
{
struct knc_state *knc = core->die->knc;
struct cgpu_info *cgpu = knc->cgpu;
@@ -465,7 +470,6 @@ static int knc_core_send_work(struct thr_info *thr, int coreid, struct knc_core_
uint8_t request[request_length];
int response_length = 1 + 1 + (1 + 4) * 5;
uint8_t response[response_length];
- int status;
int slot = knc_core_next_slot(core);
if (slot < 0)
@@ -480,20 +484,15 @@ static int knc_core_send_work(struct thr_info *thr, int coreid, struct knc_core_
if (clean) {
/* Double halt to get rid of any previous queued work */
request_length = knc_prepare_jupiter_halt(request, core->die->die, core->core);
- knc_syncronous_transfer(knc->ctx, core->die->channel, request_length, request, 0, NULL);
- knc_syncronous_transfer(knc->ctx, core->die->channel, request_length, request, 0, NULL);
+ knc_transfer(thr, core->die->channel, request_length, request, 0, KNC_NO_RESPONSE, 0);
+ knc_transfer(thr, core->die->channel, request_length, request, 0, KNC_NO_RESPONSE, 0);
}
request_length = knc_prepare_jupiter_setwork(request, core->die->die, core->core, slot, work);
- knc_syncronous_transfer(knc->ctx, core->die->channel, request_length, request, 0, NULL);
+ knc_transfer(thr, core->die->channel, request_length, request, 0, KNC_NO_RESPONSE, 0);
break;
case KNC_VERSION_NEPTUNE:
request_length = knc_prepare_neptune_setwork(request, core->die->die, core->core, slot, work, clean);
- status = knc_syncronous_transfer(knc->ctx, core->die->channel, request_length, request, response_length, response);
- if (status != KNC_ACCEPTED) {
- applog(LOG_INFO, "KnC: Communication error %x", status);
- goto error;
- }
- knc_core_process_report(thr, core, response);
+ knc_transfer(thr, core->die->channel, request_length, request, response_length, KNC_SETWORK, core->coreid);
break;
default:
goto error;
@@ -522,7 +521,7 @@ error:
return -1;
}
-static int knc_core_get_report(struct thr_info *thr, int coreid, struct knc_core_state *core)
+static int knc_core_request_report(struct thr_info *thr, struct knc_core_state *core)
{
struct knc_state *knc = core->die->knc;
struct cgpu_info *cgpu = knc->cgpu;
@@ -530,21 +529,15 @@ static int knc_core_get_report(struct thr_info *thr, int coreid, struct knc_core
uint8_t request[request_length];
int response_length = 1 + 1 + (1 + 4) * 5;
uint8_t response[response_length];
- int status;
request_length = knc_prepare_report(request, core->die->die, core->core);
switch(core->die->version) {
case KNC_VERSION_JUPITER:
response_length = 1 + 1 + (1 + 4);
- knc_syncronous_transfer(knc->ctx, core->die->channel, request_length, request, response_length, response);
- knc_core_process_report(thr, core, response);
- return 0;
+ knc_transfer(thr, core->die->channel, request_length, request, response_length, KNC_REPORT, core->coreid); return 0;
case KNC_VERSION_NEPTUNE:
- status = knc_syncronous_transfer(knc->ctx, core->die->channel, request_length, request, response_length, response);
- if (status != 0)
- break;
- knc_core_process_report(thr, core, response);
+ knc_transfer(thr, core->die->channel, request_length, request, response_length, KNC_REPORT, core->coreid);
return 0;
}
@@ -604,9 +597,9 @@ static int64_t knc_scanwork(struct thr_info *thr)
}
if (knc_core_need_work(core)) {
struct work *work = get_work(thr, thr->id);
- knc_core_send_work(thr, i, core, work, clean);
+ knc_core_send_work(thr, core, work, clean);
} else {
- knc_core_get_report(thr, i, core);
+ knc_core_request_report(thr, core);
}
}
if (knc->startup)