From 0ccab0b00204b8c23f121d4435f856775de77df6 Mon Sep 17 00:00:00 2001 From: dlg Date: Fri, 28 May 2021 02:34:38 +0000 Subject: [PATCH] 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@ --- sys/dev/ic/nvmevar.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) 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 @@ -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; -- 2.20.1