1/* $OpenBSD: nvmevar.h,v 1.30 2024/06/26 21:41:30 asou Exp $ */ 2 3/* 4 * Copyright (c) 2014 David Gwynne <dlg@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#define NVME_IO_Q 1 20#define NVME_HIB_Q 2 21#define NVME_MAXPHYS (128 * 1024) 22 23struct nvme_dmamem { 24 bus_dmamap_t ndm_map; 25 bus_dma_segment_t ndm_seg; 26 size_t ndm_size; 27 caddr_t ndm_kva; 28}; 29#define NVME_DMA_MAP(_ndm) ((_ndm)->ndm_map) 30#define NVME_DMA_LEN(_ndm) ((_ndm)->ndm_map->dm_segs[0].ds_len) 31#define NVME_DMA_DVA(_ndm) ((u_int64_t)(_ndm)->ndm_map->dm_segs[0].ds_addr) 32#define NVME_DMA_KVA(_ndm) ((void *)(_ndm)->ndm_kva) 33 34struct nvme_softc; 35 36struct nvme_ccb { 37 SIMPLEQ_ENTRY(nvme_ccb) ccb_entry; 38 39 bus_dmamap_t ccb_dmamap; 40 41 void *ccb_cookie; 42 void (*ccb_done)(struct nvme_softc *sc, 43 struct nvme_ccb *, struct nvme_cqe *); 44 45 bus_addr_t ccb_prpl_off; 46 u_int64_t ccb_prpl_dva; 47 u_int64_t *ccb_prpl; 48 49 u_int16_t ccb_id; 50}; 51SIMPLEQ_HEAD(nvme_ccb_list, nvme_ccb); 52 53struct nvme_queue { 54 struct mutex q_sq_mtx; 55 struct mutex q_cq_mtx; 56 struct nvme_dmamem *q_sq_dmamem; 57 struct nvme_dmamem *q_cq_dmamem; 58 struct nvme_dmamem *q_nvmmu_dmamem; /* for aplns(4) */ 59 bus_size_t q_sqtdbl; /* submission queue tail doorbell */ 60 bus_size_t q_cqhdbl; /* completion queue head doorbell */ 61 u_int16_t q_id; 62 u_int32_t q_entries; 63 u_int32_t q_sq_tail; 64 u_int32_t q_cq_head; 65 u_int16_t q_cq_phase; 66}; 67 68struct nvme_namespace { 69 struct nvm_identify_namespace *ident; 70}; 71 72struct nvme_ops { 73 void (*op_enable)(struct nvme_softc *); 74 75 int (*op_q_alloc)(struct nvme_softc *, 76 struct nvme_queue *); 77 void (*op_q_free)(struct nvme_softc *, 78 struct nvme_queue *); 79 80 uint32_t (*op_sq_enter)(struct nvme_softc *, 81 struct nvme_queue *, struct nvme_ccb *); 82 void (*op_sq_leave)(struct nvme_softc *, 83 struct nvme_queue *, struct nvme_ccb *); 84 uint32_t (*op_sq_enter_locked)(struct nvme_softc *, 85 struct nvme_queue *, struct nvme_ccb *); 86 void (*op_sq_leave_locked)(struct nvme_softc *, 87 struct nvme_queue *, struct nvme_ccb *); 88 89 void (*op_cq_done)(struct nvme_softc *, 90 struct nvme_queue *, struct nvme_ccb *); 91}; 92 93struct nvme_softc { 94 struct device sc_dev; 95 96 const struct nvme_ops *sc_ops; 97 u_int sc_openings; 98 99 bus_space_tag_t sc_iot; 100 bus_space_handle_t sc_ioh; 101 bus_size_t sc_ios; 102 bus_dma_tag_t sc_dmat; 103 104 void *sc_ih; 105 106 u_int sc_rdy_to; 107 size_t sc_mps; 108 size_t sc_mdts; 109 u_int sc_max_prpl; 110 u_int sc_dstrd; 111 112 struct nvm_identify_controller 113 sc_identify; 114 115 u_int sc_nn; 116 struct nvme_namespace *sc_namespaces; 117 118 struct nvme_queue *sc_admin_q; 119 struct nvme_queue *sc_q; 120 struct nvme_queue *sc_hib_q; 121 122 struct mutex sc_ccb_mtx; 123 struct nvme_ccb *sc_ccbs; 124 struct nvme_ccb_list sc_ccb_list; 125 struct nvme_dmamem *sc_ccb_prpls; 126 struct scsi_iopool sc_iopool; 127 struct rwlock sc_lock; 128 struct scsibus_softc *sc_scsibus; 129}; 130 131#define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname) 132 133int nvme_attach(struct nvme_softc *); 134int nvme_activate(struct nvme_softc *, int); 135int nvme_intr(void *); 136int nvme_intr_intx(void *); 137 138#define nvme_read4(_s, _r) \ 139 bus_space_read_4((_s)->sc_iot, (_s)->sc_ioh, (_r)) 140#define nvme_write4(_s, _r, _v) \ 141 bus_space_write_4((_s)->sc_iot, (_s)->sc_ioh, (_r), (_v)) 142 143u_int64_t 144 nvme_read8(struct nvme_softc *, bus_size_t); 145void nvme_write8(struct nvme_softc *, bus_size_t, u_int64_t); 146 147#define nvme_barrier(_s, _r, _l, _f) \ 148 bus_space_barrier((_s)->sc_iot, (_s)->sc_ioh, (_r), (_l), (_f)) 149 150struct nvme_dmamem * 151 nvme_dmamem_alloc(struct nvme_softc *, size_t); 152void nvme_dmamem_free(struct nvme_softc *, struct nvme_dmamem *); 153void nvme_dmamem_sync(struct nvme_softc *, struct nvme_dmamem *, int); 154