summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-04-14 10:26:34 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-04-14 10:26:34 +0000
commit1f16d0bb2330b81223fb626ae8a17335ad06f231 (patch)
tree421ddb0fde0cae53e7a5a6294f000553225ded68 /sys/dev
parent69ead91c2c63bf223f6d48c6a4d72e749a9368c2 (diff)
implement translation of scsi SYNC CACHE to nvme FLUSH
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/nvme.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/sys/dev/ic/nvme.c b/sys/dev/ic/nvme.c
index b25b3843c75..b414df21883 100644
--- a/sys/dev/ic/nvme.c
+++ b/sys/dev/ic/nvme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nvme.c,v 1.44 2016/04/14 09:07:30 dlg Exp $ */
+/* $OpenBSD: nvme.c,v 1.45 2016/04/14 10:26:33 dlg Exp $ */
/*
* Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
@@ -100,6 +100,11 @@ void nvme_scsi_io_fill(struct nvme_softc *, struct nvme_ccb *,
void nvme_scsi_io_done(struct nvme_softc *, struct nvme_ccb *,
struct nvme_cqe *);
+void nvme_scsi_sync(struct scsi_xfer *);
+void nvme_scsi_sync_fill(struct nvme_softc *, struct nvme_ccb *, void *);
+void nvme_scsi_sync_done(struct nvme_softc *, struct nvme_ccb *,
+ struct nvme_cqe *);
+
void nvme_scsi_inq(struct scsi_xfer *);
void nvme_scsi_inquiry(struct scsi_xfer *);
void nvme_scsi_capacity16(struct scsi_xfer *);
@@ -466,6 +471,10 @@ nvme_scsi_cmd(struct scsi_xfer *xs)
nvme_scsi_io(xs, nvme_scsi_wr_fill);
return;
+ case SYNCHRONIZE_CACHE:
+ nvme_scsi_sync(xs);
+ return;
+
case INQUIRY:
nvme_scsi_inq(xs);
return;
@@ -619,6 +628,51 @@ nvme_scsi_io_done(struct nvme_softc *sc, struct nvme_ccb *ccb,
}
void
+nvme_scsi_sync(struct scsi_xfer *xs)
+{
+ struct scsi_link *link = xs->sc_link;
+ struct nvme_softc *sc = link->adapter_softc;
+ struct nvme_ccb *ccb = xs->io;
+
+ ccb->ccb_done = nvme_scsi_sync_done;
+ ccb->ccb_cookie = xs;
+
+ if (ISSET(xs->flags, SCSI_POLL)) {
+ nvme_poll(sc, sc->sc_q, ccb, nvme_scsi_sync_fill);
+ return;
+ }
+
+ nvme_q_submit(sc, sc->sc_q, ccb, nvme_scsi_sync_fill);
+}
+
+void
+nvme_scsi_sync_fill(struct nvme_softc *sc, struct nvme_ccb *ccb, void *slot)
+{
+ struct nvme_sqe *sqe = slot;
+ struct scsi_xfer *xs = ccb->ccb_cookie;
+ struct scsi_link *link = xs->sc_link;
+
+ sqe->opcode = NVM_CMD_FLUSH;
+ htolem32(&sqe->nsid, link->target + 1);
+}
+
+void
+nvme_scsi_sync_done(struct nvme_softc *sc, struct nvme_ccb *ccb,
+ struct nvme_cqe *cqe)
+{
+ struct scsi_xfer *xs = ccb->ccb_cookie;
+ u_int16_t flags;
+
+ flags = lemtoh16(&cqe->flags);
+
+ xs->error = (NVME_CQE_SC(flags) == NVME_CQE_SC_SUCCESS) ?
+ XS_NOERROR : XS_DRIVER_STUFFUP;
+ xs->status = SCSI_OK;
+ xs->resid = 0;
+ scsi_done(xs);
+}
+
+void
nvme_scsi_inq(struct scsi_xfer *xs)
{
struct scsi_inquiry *inq = (struct scsi_inquiry *)xs->cmd;