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