diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2016-04-13 13:13:28 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2016-04-13 13:13:28 +0000 |
commit | 495b49bc86244da213b743be5db2839da1a982f5 (patch) | |
tree | ccc94483b6a3d1e2249cbef5bec32321e6fe504d /sys/dev/ic/nvme.c | |
parent | f290f8f7ec910e6ee096d6d0d087b3b784f0252e (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.c | 47 |
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) { |