Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic switch handling of passthrough commands to use qu...



details:   https://anonhg.NetBSD.org/src/rev/d29aae454f6a
branches:  trunk
changeset: 321459:d29aae454f6a
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Sat Mar 17 00:28:03 2018 +0000

description:
switch handling of passthrough commands to use queue, instead of polling

should fix PR kern/53059 by Frank Kardel

diffstat:

 sys/dev/ic/nvme.c |  48 +++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 37 insertions(+), 11 deletions(-)

diffs (113 lines):

diff -r 651cb3e2a226 -r d29aae454f6a sys/dev/ic/nvme.c
--- a/sys/dev/ic/nvme.c Sat Mar 17 00:03:25 2018 +0000
+++ b/sys/dev/ic/nvme.c Sat Mar 17 00:28:03 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvme.c,v 1.34 2018/03/16 23:31:19 jdolecek Exp $       */
+/*     $NetBSD: nvme.c,v 1.35 2018/03/17 00:28:03 jdolecek Exp $       */
 /*     $OpenBSD: nvme.c,v 1.49 2016/04/18 05:59:50 dlg Exp $ */
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.34 2018/03/16 23:31:19 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.35 2018/03/17 00:28:03 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -929,12 +929,18 @@
                kmem_free(identify, sizeof(*identify));
 }
 
+struct nvme_pt_state {
+       struct nvme_pt_command *pt;
+       bool finished;
+};
+
 static void
 nvme_pt_fill(struct nvme_queue *q, struct nvme_ccb *ccb, void *slot)
 {
        struct nvme_softc *sc = q->q_sc;
        struct nvme_sqe *sqe = slot;
-       struct nvme_pt_command *pt = ccb->ccb_cookie;
+       struct nvme_pt_state *state = ccb->ccb_cookie;
+       struct nvme_pt_command *pt = state->pt;
        bus_dmamap_t dmap = ccb->ccb_dmamap;
        int i;
 
@@ -976,7 +982,8 @@
 nvme_pt_done(struct nvme_queue *q, struct nvme_ccb *ccb, struct nvme_cqe *cqe)
 {
        struct nvme_softc *sc = q->q_sc;
-       struct nvme_pt_command *pt = ccb->ccb_cookie;
+       struct nvme_pt_state *state = ccb->ccb_cookie;
+       struct nvme_pt_command *pt = state->pt;
        bus_dmamap_t dmap = ccb->ccb_dmamap;
 
        if (pt->buf != NULL && pt->len > 0) {
@@ -995,6 +1002,18 @@
 
        pt->cpl.cdw0 = lemtoh32(&cqe->cdw0);
        pt->cpl.flags = lemtoh16(&cqe->flags) & ~NVME_CQE_PHASE;
+
+       state->finished = true;
+
+       nvme_ccb_put(q, ccb);
+}
+
+static bool
+nvme_pt_finished(void *cookie)
+{
+       struct nvme_pt_state *state = cookie;
+
+       return state->finished;
 }
 
 static int
@@ -1004,6 +1023,7 @@
        struct nvme_queue *q;
        struct nvme_ccb *ccb;
        void *buf = NULL;
+       struct nvme_pt_state state;
        int error;
 
        /* limit command size to maximum data transfer size */
@@ -1034,24 +1054,30 @@
                    pt->is_read ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
        }
 
+       memset(&state, 0, sizeof(state));
+       state.pt = pt;
+       state.finished = false;
+
        ccb->ccb_done = nvme_pt_done;
-       ccb->ccb_cookie = pt;
+       ccb->ccb_cookie = &state;
 
        pt->cmd.nsid = nsid;
-       if (nvme_poll(sc, q, ccb, nvme_pt_fill, NVME_TIMO_PT)) {
-               error = EIO;
-               goto out;
-       }
+
+       nvme_q_submit(sc, q, ccb, nvme_pt_fill);
+
+       /* wait for completion */
+       nvme_q_wait_complete(sc, q, nvme_pt_finished, &state);
+       KASSERT(state.finished);
 
        error = 0;
-out:
+
        if (buf != NULL) {
                if (error == 0 && pt->is_read)
                        error = copyout(buf, pt->buf, pt->len);
 kmem_free:
                kmem_free(buf, pt->len);
        }
-       nvme_ccb_put(q, ccb);
+
        return error;
 }
 



Home | Main Index | Thread Index | Old Index