summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2017-03-30 23:33:46 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2017-03-30 23:33:46 +0200
commit8cacd2cc0aa7bc7b51c0017edcd6a49db5b4f95e (patch)
tree61533893082214283429b8df4219e691880b3504
parente51044884b329d808015c7972d1c8409303faab3 (diff)
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.
-rw-r--r--sys/src/9/pc/sdnvme.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/sys/src/9/pc/sdnvme.c b/sys/src/9/pc/sdnvme.c
index c8605c0d2..537578d5d 100644
--- a/sys/src/9/pc/sdnvme.c
+++ b/sys/src/9/pc/sdnvme.c
@@ -165,7 +165,7 @@ nvmeintr(Ureg *, void *arg)
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 @@ nvmeintr(Ureg *, void *arg)
*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);
}