diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2021-05-28 02:34:39 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2021-05-28 02:34:39 +0000 |
commit | 5115fe90052de03bb9134a60c1c2df41d5fecb1a (patch) | |
tree | a65ac9f1f48e2108163ed65b67232ab86dfca4b2 /sys/dev/ic | |
parent | 7dc93fd9938cc6585d234b709473b88409ca25f8 (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.h | 25 |
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; |