summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2021-05-28 02:34:39 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2021-05-28 02:34:39 +0000
commit5115fe90052de03bb9134a60c1c2df41d5fecb1a (patch)
treea65ac9f1f48e2108163ed65b67232ab86dfca4b2 /sys/dev/ic
parent7dc93fd9938cc6585d234b709473b88409ca25f8 (diff)
provide an nvme_ops struct to start trying to support apple m1 nvme.
the Apple NVME Storage (ans) controller is almost but not quite a vanilla nvme controller. one difference is that it doesnt attach to a pci bus, so it will need custom bus glue to attach on those machines. the other differences are around command submission. vanilla nvme command submission is done via rings where the host fills in one or more entries on the ring and then posts where the ring is up to in a doorbell. ans nvme command submission is done via an array of command slots where the host picks a slot and then posts every slot number it fills in to a doorbell instead. this is kind of clever because once a command slot is allocated, you don't need any coordination between multiple cpus using that array of slots to fill in and post the entry they were allocated. on the other hand, it's different, so the code needs to be specialised. ans also seems to have some weird iommu thing that needs to be maintained as commands are posted and completed. the nvme_ops struct will allow vanilla and ans controllers to provide their own backens for these different semantics. ok jmatthew@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/nvmevar.h25
1 files changed, 24 insertions, 1 deletions
diff --git a/sys/dev/ic/nvmevar.h b/sys/dev/ic/nvmevar.h
index 1ea682d7ab5..dae2b07d1e7 100644
--- a/sys/dev/ic/nvmevar.h
+++ b/sys/dev/ic/nvmevar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nvmevar.h,v 1.25 2021/05/28 02:03:11 dlg Exp $ */
+/* $OpenBSD: nvmevar.h,v 1.26 2021/05/28 02:34:38 dlg Exp $ */
/*
* Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
@@ -69,9 +69,32 @@ struct nvme_namespace {
struct nvm_identify_namespace *ident;
};
+struct nvme_ops {
+ void (*op_enable)(struct nvme_softc *);
+
+ int (*op_q_alloc)(struct nvme_softc *,
+ struct nvme_queue *);
+ void (*op_q_free)(struct nvme_softc *,
+ struct nvme_queue *);
+
+ uint32_t (*op_sq_enter)(struct nvme_softc *,
+ struct nvme_queue *, struct nvme_ccb *);
+ void (*op_sq_leave)(struct nvme_softc *,
+ struct nvme_queue *, struct nvme_ccb *);
+ uint32_t (*op_sq_enter_locked)(struct nvme_softc *,
+ struct nvme_queue *, struct nvme_ccb *);
+ void (*op_sq_leave_locked)(struct nvme_softc *,
+ struct nvme_queue *, struct nvme_ccb *);
+
+ void (*op_cq_done)(struct nvme_softc *,
+ struct nvme_queue *, struct nvme_ccb *);
+};
+
struct nvme_softc {
struct device sc_dev;
+ const struct nvme_ops *sc_ops;
+
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_size_t sc_ios;