ref: 8cacd2cc0aa7bc7b51c0017edcd6a49db5b4f95e
parent: e51044884b329d808015c7972d1c8409303faab3
author: cinap_lenrek <[email protected]>
date: Thu Mar 30 19:33:46 EDT 2017
sdnvme: don't write completion queue doorbell register when nothing has been processed turns out on real hardware, the front falls off if we write the completion queue doorbell registers without consuming an entry. so only write the register when we have processed something.
--- a/sys/src/9/pc/sdnvme.c
+++ b/sys/src/9/pc/sdnvme.c
@@ -165,7 +165,7 @@
if(cq->base == nil)
continue;
phaseshift = 16 - cq->shift;
- for(;; cq->head++){
+ for(;;){
e = &cq->base[(cq->head & cq->mask)<<2];
if(((e[3] ^ (cq->head << phaseshift)) & 0x10000) == 0)
break;
@@ -183,11 +183,9 @@
*wp = nil;
wakeup(z);
}
+ ctlr->reg[DBell + ((cq-ctlr->cq)*2+1 << ctlr->dstrd)] = ++cq->head & cq->mask;
}
- ctlr->reg[DBell + ((cq-ctlr->cq)*2+1 << ctlr->dstrd)] = cq->head & cq->mask;
}
- if((ctlr->reg[CSts] & 3) != 1)
- iprint("nvmeintr: fatal controller error\n");
ctlr->reg[IntMc] = ctlr->ints;
iunlock(&ctlr->intr);
}