1 /* $OpenBSD: nvmevar.h,v 1.31 2024/09/13 09:57:34 jmatthew 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 #include <sys/sensors.h> 20 21 #define NVME_IO_Q 1 22 #define NVME_HIB_Q 2 23 #define NVME_MAXPHYS (128 * 1024) 24 25 struct nvme_dmamem { 26 bus_dmamap_t ndm_map; 27 bus_dma_segment_t ndm_seg; 28 size_t ndm_size; 29 caddr_t ndm_kva; 30 }; 31 #define NVME_DMA_MAP(_ndm) ((_ndm)->ndm_map) 32 #define NVME_DMA_LEN(_ndm) ((_ndm)->ndm_map->dm_segs[0].ds_len) 33 #define NVME_DMA_DVA(_ndm) ((u_int64_t)(_ndm)->ndm_map->dm_segs[0].ds_addr) 34 #define NVME_DMA_KVA(_ndm) ((void *)(_ndm)->ndm_kva) 35 36 struct nvme_softc; 37 38 struct nvme_ccb { 39 SIMPLEQ_ENTRY(nvme_ccb) ccb_entry; 40 41 bus_dmamap_t ccb_dmamap; 42 43 void *ccb_cookie; 44 void (*ccb_done)(struct nvme_softc *sc, 45 struct nvme_ccb *, struct nvme_cqe *); 46 47 bus_addr_t ccb_prpl_off; 48 u_int64_t ccb_prpl_dva; 49 u_int64_t *ccb_prpl; 50 51 u_int16_t ccb_id; 52 }; 53 SIMPLEQ_HEAD(nvme_ccb_list, nvme_ccb); 54 55 struct nvme_queue { 56 struct mutex q_sq_mtx; 57 struct mutex q_cq_mtx; 58 struct nvme_dmamem *q_sq_dmamem; 59 struct nvme_dmamem *q_cq_dmamem; 60 struct nvme_dmamem *q_nvmmu_dmamem; /* for aplns(4) */ 61 bus_size_t q_sqtdbl; /* submission queue tail doorbell */ 62 bus_size_t q_cqhdbl; /* completion queue head doorbell */ 63 u_int16_t q_id; 64 u_int32_t q_entries; 65 u_int32_t q_sq_tail; 66 u_int32_t q_cq_head; 67 u_int16_t q_cq_phase; 68 }; 69 70 struct nvme_namespace { 71 struct nvm_identify_namespace *ident; 72 }; 73 74 struct nvme_ops { 75 void (*op_enable)(struct nvme_softc *); 76 77 int (*op_q_alloc)(struct nvme_softc *, 78 struct nvme_queue *); 79 void (*op_q_free)(struct nvme_softc *, 80 struct nvme_queue *); 81 82 uint32_t (*op_sq_enter)(struct nvme_softc *, 83 struct nvme_queue *, struct nvme_ccb *); 84 void (*op_sq_leave)(struct nvme_softc *, 85 struct nvme_queue *, struct nvme_ccb *); 86 uint32_t (*op_sq_enter_locked)(struct nvme_softc *, 87 struct nvme_queue *, struct nvme_ccb *); 88 void (*op_sq_leave_locked)(struct nvme_softc *, 89 struct nvme_queue *, struct nvme_ccb *); 90 91 void (*op_cq_done)(struct nvme_softc *, 92 struct nvme_queue *, struct nvme_ccb *); 93 }; 94 95 struct nvme_softc { 96 struct device sc_dev; 97 98 const struct nvme_ops *sc_ops; 99 u_int sc_openings; 100 101 bus_space_tag_t sc_iot; 102 bus_space_handle_t sc_ioh; 103 bus_size_t sc_ios; 104 bus_dma_tag_t sc_dmat; 105 106 void *sc_ih; 107 108 u_int sc_rdy_to; 109 size_t sc_mps; 110 size_t sc_mdts; 111 u_int sc_max_prpl; 112 u_int sc_dstrd; 113 114 struct nvm_identify_controller 115 sc_identify; 116 117 u_int sc_nn; 118 struct nvme_namespace *sc_namespaces; 119 120 struct nvme_queue *sc_admin_q; 121 struct nvme_queue *sc_q; 122 struct nvme_queue *sc_hib_q; 123 124 struct mutex sc_ccb_mtx; 125 struct nvme_ccb *sc_ccbs; 126 struct nvme_ccb_list sc_ccb_list; 127 struct nvme_dmamem *sc_ccb_prpls; 128 struct scsi_iopool sc_iopool; 129 struct rwlock sc_lock; 130 struct scsibus_softc *sc_scsibus; 131 132 struct ksensordev sc_sensordev; 133 struct ksensor sc_temp_sensor; 134 struct ksensor sc_spare_sensor; 135 struct ksensor sc_usage_sensor; 136 }; 137 138 #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname) 139 140 int nvme_attach(struct nvme_softc *); 141 int nvme_activate(struct nvme_softc *, int); 142 int nvme_intr(void *); 143 int nvme_intr_intx(void *); 144 145 #define nvme_read4(_s, _r) \ 146 bus_space_read_4((_s)->sc_iot, (_s)->sc_ioh, (_r)) 147 #define nvme_write4(_s, _r, _v) \ 148 bus_space_write_4((_s)->sc_iot, (_s)->sc_ioh, (_r), (_v)) 149 150 u_int64_t 151 nvme_read8(struct nvme_softc *, bus_size_t); 152 void nvme_write8(struct nvme_softc *, bus_size_t, u_int64_t); 153 154 #define nvme_barrier(_s, _r, _l, _f) \ 155 bus_space_barrier((_s)->sc_iot, (_s)->sc_ioh, (_r), (_l), (_f)) 156 157 struct nvme_dmamem * 158 nvme_dmamem_alloc(struct nvme_softc *, size_t); 159 void nvme_dmamem_free(struct nvme_softc *, struct nvme_dmamem *); 160 void nvme_dmamem_sync(struct nvme_softc *, struct nvme_dmamem *, int); 161