summaryrefslogtreecommitdiff
path: root/sys/dev/ic/nvme.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-04-13 13:13:28 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-04-13 13:13:28 +0000
commit495b49bc86244da213b743be5db2839da1a982f5 (patch)
treeccc94483b6a3d1e2249cbef5bec32321e6fe504d /sys/dev/ic/nvme.c
parentf290f8f7ec910e6ee096d6d0d087b3b784f0252e (diff)
nvme_q_create() issues the commands to tell the chip about io queues
Diffstat (limited to 'sys/dev/ic/nvme.c')
-rw-r--r--sys/dev/ic/nvme.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c
index 566ef386261..8c6d66e3e70 100644
--- a/sys/dev/ic/nvme.c
+++ b/sys/dev/ic/nvme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nvme.c,v 1.29 2016/04/13 13:09:36 dlg Exp $ */
+/* $OpenBSD: nvme.c,v 1.30 2016/04/13 13:13:27 dlg Exp $ */
/*
* Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
@@ -67,6 +67,7 @@ void nvme_empty_done(struct nvme_softc *, struct nvme_ccb *,
struct nvme_queue *
nvme_q_alloc(struct nvme_softc *, u_int16_t, u_int, u_int);
+int nvme_q_create(struct nvme_softc *, struct nvme_queue *);
void nvme_q_submit(struct nvme_softc *,
struct nvme_queue *, struct nvme_ccb *,
void (*)(struct nvme_softc *, struct nvme_ccb *, void *));
@@ -759,6 +760,50 @@ done:
return (rv);
}
+int
+nvme_q_create(struct nvme_softc *sc, struct nvme_queue *q)
+{
+ struct nvme_sqe_q sqe;
+ struct nvme_ccb *ccb;
+ int rv;
+
+ ccb = scsi_io_get(&sc->sc_iopool, 0);
+ KASSERT(ccb != NULL);
+
+ ccb->ccb_done = nvme_empty_done;
+ ccb->ccb_cookie = &sqe;
+
+ memset(&sqe, 0, sizeof(sqe));
+ sqe.opcode = NVM_ADMIN_ADD_IOCQ;
+ htolem64(&sqe.prp1, NVME_DMA_DVA(q->q_cq_dmamem));
+ htolem16(&sqe.qsize, q->q_entries - 1);
+ htolem16(&sqe.qid, q->q_id);
+ sqe.qflags = NVM_SQE_CQ_IEN | NVM_SQE_Q_PC;
+
+ rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
+ if (rv != 0)
+ goto fail;
+
+ ccb->ccb_done = nvme_empty_done;
+ ccb->ccb_cookie = &sqe;
+
+ memset(&sqe, 0, sizeof(sqe));
+ sqe.opcode = NVM_ADMIN_ADD_IOSQ;
+ htolem64(&sqe.prp1, NVME_DMA_DVA(q->q_sq_dmamem));
+ htolem16(&sqe.qsize, q->q_entries - 1);
+ htolem16(&sqe.qid, q->q_id);
+ htolem16(&sqe.cqid, q->q_id);
+ sqe.qflags = NVM_SQE_Q_PC;
+
+ rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_sqe_fill);
+ if (rv != 0)
+ goto fail;
+
+fail:
+ scsi_io_put(&sc->sc_iopool, ccb);
+ return (rv);
+}
+
void
nvme_fill_identify(struct nvme_softc *sc, struct nvme_ccb *ccb, void *slot)
{